QCHack will consist of two parts: the Hackathon,

The post Announcing Microsoft Quantum challenge at QCHack appeared first on Q# Blog.

]]>QCHack will consist of two parts: the Hackathon, running for 24 hours during the weekend of April 10-11, and the pre-Hackathon bootcamp during the week of April 5-9.

The bootcamp will help participants get started with their Hackathon preparation. It will include tutorials on quantum computing and on quantum programming toolkits offered by the sponsor companies that will be used in their respective challenges. The participants will also have ample opportunities to meet quantum computing professionals from the sponsor companies, to learn more about the cutting-edge research done by them and about their journeys in quantum computing.

Check out the QCHack schedule for the complete list of tutorials, panels, and social events planned for the bootcamp week!

The weekend of April 10-11 will be the time when the participants will put their newly acquired quantum computing skills to test. Each company will offer a unique challenge focused on their toolkit and using it to solve a certain problem, revealed at the kick-off ceremony on April 10^{th}. The teams will then have 24 hours to do their best at solving the challenges, and afterward, the judges from each company will pick the winners of their challenge.

Of course, you must be curious about what challenge Microsoft Quantum will offer to the QCHack participants. Let me give you a couple of spoilers without giving away too much.

Our challenge focuses on Microsoft Quantum Development Kit and Q#, and will consist of two parts:

- Warmup problems. To start with, you’ll be offered several problems of increasing difficulty that solve tasks similar to the ones you’ll need to handle in the second part of the challenge. These tasks will come with testing harnesses, similar to the ones used in the Quantum Katas, so that you’ll be able to check whether your solutions are correct. The submissions will be judged automatically using the same or similar testing harnesses: if your code for the problem passes the tests, you get the points for it!
- Free-form challenge. In this part, you’ll create a project that solves a quantum computing problem within certain constraints. There will be no “right” or “wrong” way to solve this challenge; you have the freedom to decide what you want to do! The submissions will be judged on several criteria, such as creativity, technical depth, and the educational value of the project.

The points from both parts of the challenge will be added together, and the highest-scoring teams will be declared winners! The challenge will have prizes, as well as an opportunity for the winning teams to present their projects to the Microsoft Quantum team after the event.

If you’re excited about this event and can’t wait to get started, here are the next steps for you:

- Register for it.
- Start learning as much as you can about quantum computing and the sponsor companies’ tools!

And here are several good ways to practice for the Microsoft Quantum challenge:

- The Quantum Katas offer a collection of tutorials and programming exercises covering the basic concepts and algorithms of quantum computing. They are a great way both to get started with quantum computing and Q# programming and to get familiar with the types of tasks that can be offered in the first part of the challenge.
- The past Q# Coding Contests are another collection of Q# programming problems that you can use for practice. Be warned, though, that the current QDK version used on the Codeforces platform is 0.11, so the Q# syntax accepted there will differ slightly from the latest one.

I’m looking forward to the QCHack, and I hope to see you there!

The post Announcing Microsoft Quantum challenge at QCHack appeared first on Q# Blog.

]]>Quantum computers will be able to reveal the exact quantum nature of chemical systems exponentially faster than classical computers. That’s why one of the most impactful future applications of quantum computing is chemistry simulation.

The post Quantum developer tools for chemistry appeared first on Q# Blog.

]]>

Quantum computers will be able to reveal the exact quantum nature of chemical systems exponentially faster than classical computers. That’s why one of the most impactful future applications of quantum computing is chemistry simulation. Quantum mechanics plays a dominant role in the behavior of molecular systems at the fundamental scales. However, the complex nature of quantum effects make them computationally expensive to simulate. For instance, a simple, approximate quantum chemistry calculation could take many hours to run on a large computational cluster. While exact calculations may even be intractable for these classical systems, quantum computers can reveal the exact quantum nature of chemical systems. Such advantage can unlock the ability to study molecules and chemical phenomena we were not able to study before. If you are interested in what chemical systems can benefit most from quantum computers, please take a look at our latest work: Prospects of Quantum Computing for Molecular Sciences.

To get started with quantum development of chemistry algorithms, you can either run quantum algorithms on a simulator or on near-term hardware. Simulators can be a great way to get started with quantum programming, and they also offer a way to understand the hardware requirements of a specific algorithm. The Microsoft Quantum Development Kit (QDK) offers multiple simulator back-ends that can be targeted by the Q# compiler and runtime. In addition, we offer Python-based tools that easily let you plug in your favorite libraries to analyze and plot the results. Many of the chemistry tools in the QDK have resulted from work done by our research team in collaboration with the Advanced Computing, Mathematics, and Data Division at Pacific Northwest National Laboratory (PNNL). Some of our tools include interacting with the Microsoft Quantum Editor on EMSL Arrows, a computational chemistry tool built and maintained by the PNNL team. In this post we will show examples of chemistry algorithms that you can run with the QDK and the Q# Chemistry library.

Energy is one of the most important properties of a molecule from the computational perspective. It can be directly translated to metrics and design principles to guide real-world application, for instance the design of catalysts or photovoltaic materials. As most of the time molecules are in their ground state, i.e. lowest energy state, the evaluation of ground state energy thus becomes the most fundamental step to understand the molecule. A scalable and powerful algorithm that can be used to calculate the ground state is called Quantum Phase Estimation (QPE). QPE projects the quantum state onto an eigen state of the Hamiltonian of the molecule, such that it always produces exact energies. Here we will demonstrate how to run Robust Phase Estimation, a version of Quantum Phase Estimation algorithm that uses fewer qubits, using the QDK developer tools for chemistry. This calculation consists roughly of the following steps:

- Compute the electron interactions (i.e. Hamiltonian terms) using chemistry simulation packages such as NWChem.
- From the results in (1), generate the coefficients for generating a good guess of the ground state, also known as a
*trial state*, to encode in qubits. Optionally, it is possible here to perform further calculations in chemistry packages to get an elaborate trial state if higher accuracy is required in the estimation. - Apply Robust Phase Estimation algorithm to estimate the phase of the trial state. This prepares the trial state generated in (2) and projects the state onto a possible ground state of the Hamiltonian.
- Repeat (3) and post-select to find the solution that provides the lowest energy.

In the example below, we will run a Q# program that runs Robust Phase Estimation on a simulator, in particular, the Q# full state simulator. The Q# program is defined in a Q# file and contains an operation that we can import and run from a Q# entry point, the IQ# kernel, a host program in C# or Python, or directly from a Jupyter notebook, as we will do in this blog post.

namespace Microsoft.Quantum.Chemistry.Trotterization { open Microsoft.Quantum.Core; open Microsoft.Quantum.Intrinsic; open Microsoft.Quantum.Canon; open Microsoft.Quantum.Chemistry; open Microsoft.Quantum.Chemistry.JordanWigner; open Microsoft.Quantum.Simulation; open Microsoft.Quantum.Characterization; open Microsoft.Quantum.Convert; open Microsoft.Quantum.Math; operation GetEnergyRPE ( JWEncodedData: JordanWignerEncodingData, nBitsPrecision : Int, trotterStepSize : Double, trotterOrder : Int ) : (Double, Double) { let (nSpinOrbitals, fermionTermData, inputState, energyOffset) = JWEncodedData!; let (nQubits, (rescaleFactor, oracle)) = TrotterStepOracle(JWEncodedData, trotterStepSize, trotterOrder); let statePrep = PrepareTrialState(inputState, _); let phaseEstAlgorithm = RobustPhaseEstimation(nBitsPrecision, _, _); let estPhase = EstimateEnergy(nQubits, statePrep, oracle, phaseEstAlgorithm); let estEnergy = estPhase * rescaleFactor + energyOffset; return (estPhase, estEnergy); } }

This operation makes use of the Q# Libraries, in particular the Quantum Chemistry Library, and will return a tuple of the estimated phase and energy of the ground state of the molecule. For more information on the above libraries and operations used in this sample, please take a look at the extensive Q# user guide.

To start off calculating the ground state, we need to first load the molecule such that we can construct its electronic model. Here, we will use an XYZ file, which specifies the spatial coordinates of the atoms in the molecule. To inspect the molecule, we can use the qdk Python package and visualize it in Jupyter notebook. To install the qdk package and its dependencies, we recommend installing conda and running:

$ conda install -c rdkit rdkit $ pip install qdk

If you don’t have it already, make sure to also install the qsharp package:

$ conda install –c quantum-engineering qsharp

Now, start a Jupyter notebook by running:

$ jupyter notebook

This opens a new browser window with a Jupyter server, from which you can start a new notebook with a Python kernel. To load the molecule inside the notebook, simply import the Molecule class and use the from_xyz class method to create an instance:

In: from qdk.chemistry import Molecule caffeine = Molecule.from_xyz("data/xyz/caffeine.xyz") caffeine Out:

This returns an interactive JSMol widget in the notebook.

For a static image of the molecule generated by RDKit, run:

In: caffeine.mol Out:

We can then inspect how many electrons this molecule has:

In: caffeine.num_electrons Out: 102

And the atomic number of its atoms:

In: caffeine.atoms Out: [1, 6, 7, 8]

To evaluate the energy of a molecule, we need to choose a set of one-electron basis functions (often known as orbitals) to represent the electronic wave functions. Here, we use one of the most elementary basis sets, STO-3G, to represent the caffeine molecule:

In: caffeine.num_orbitals(basis="STO-3G") Out: 80

In total, there are 80 spatial orbitals. The state of an orbital, which can contain up to two electrons, can be represented by 2 qubits. One can easily see that the classical simulation of many orbitals is very costly due to the exponential complexity of simulating qubits. Luckily, only a couple of frontier orbitals (in many cases, the highest-occupied-molecular-orbital, HOMOs; and lowest-unoccupied-molecular-orbital, LUMOs) dominate the chemical properties of the molecule. We only need to probe the molecule’s quantum properties within those chemically most relevant orbitals, also known as *active space*, and use approximations to estimate the energy contribution of rest of the orbitals. This largely reduces the number of orbitals we need to map to the qubits.

For this problem, we can start off with four active orbitals, which means we will need 8 qubits to encode the problem. RPE also requires one auxiliary qubit, which would bring us to 9 qubits in total, which is a number we can comfortably simulate on a laptop. To do that, we need to calculate the electronic properties using a computation chemistry tool such as NWChem or OpenMolcas. To use NWChem in the browser and generate a Broombridge file directly, use the Microsoft Quantum Editor on EMSL Arrows.

To encode the electronic properties, also known as the electrionic Hamiltonian, we need to store them in a file format using the Broombridge Quantum Chemistry Schema. You can use the following Python code to load it via the QDK Python package:

In: from qdk.chemistry.broombridge import load_and_encode encoded_data_caffeine = load_and_encode("data/broombridge/caffeine.yaml")

Then we can import and call the Q# operation from Python:

In: from Microsoft.Quantum.Chemistry.RPE import GetEnergyRPE GetEnergyRPE.simulate( JWEncodedData=encoded_data_caffeine, nBitsPrecision=10, trotterStepSize=0.2, trotterOrder=1 ) Out: (-0.3383813350711708, -627.6309264967134)

By classical simulations we found the exact ground state energy to be `-627.63095945558848 Ha`

. Given that we are using 10 bits of precision with a step size of 0.2, we expect an error of (1/2^{10})/0.2=4*10^{-3}, which is 4 mHa accuracy, so our result from RPE is within the expected error range.

To see how resource intensive this calculation was, we can use the `estimate_resources`

method:

In: GetEnergyRPE.estimate_resources( JWEncodedData=encoded_data_caffeine, nBitsPrecision=10, trotterStepSize=0.2, trotterOrder=1 )

This will calculate the resources and return a Python dictionary:

Out: { 'CNOT': 42913920, 'QubitClifford': 24522844, 'R': 9196140, 'Measure': 609, 'T': 0, 'Depth': 0, 'Width': 9, 'QubitCount': 9, 'BorrowedWidth': 0 }

Here, the values in the dictionary return the estimates of numbers of different gates and circuit depth required to run this algorithm. To learn more about what each of these metrics represent, please visit the “Metrics reported” section of the docs of the Q# resources estimator simulator back-end.

Based on the resource metrics, it looks like simulating the ground state of caffeine using RPE requires quite a lot of resources. We need many millions of CNOT gates! Obviously, this is not yet realistic on near-term hardware, such as the systems available on Azure Quantum. So how are we going to simulate a chemistry molecule on a near-term machine? For this purpose, variational methods might come in handy.

While Quantum Phase Estimation algorithms such as the RPE sample mentioned above provide an exact solution, there are variational methods in chemistry that are used to iteratively get to an approximate solution. We can do exactly that using small and shallow quantum algorithms such as the Variational Quantum Eigensolver. The VQE algorithm starts with a *parameterized trial state*, and optimizes the parameters to approximate the ground state energy. The protocol is as follows:

- Compute the electron interactions (i.e. Hamiltonian terms) using a chemistry simulation package.
- From the results in (1), generat a good guess of the ground state
*(trial**state*), and encode it in qubits. - Estimate the energy of the trial state by doing a projective measurement for each term in the Hamiltonian.
- Modify the trial state using its parametric definition.
- Repeat steps 2 to 4 until the energy of the molecule is minimized.

The algorithm requires many evaluations on quantum hardware, but this will give us an approximation of the ground state. The Q# program that implements VQE uses the EstimateEnergy operation which uses EstimateFrequencyA to estimate the fraction of samples of a projected measurement that are in the Zero state. This operation is run using a built-in emulation feature in the simulator that uses binomial sampling to simulate running multiple shots on quantum hardware without directly inspecting the quantum state, which allows us to run the VQE algorithm on millions of shots without any significant added run time. Note that on real hardware, this emulation is not possible, so it would take a significantly longer time to run.

The Q# program is shown below. The operation takes the Hamiltonian information, then encodes the wave function ansatz as a linear combination of the Hartree-Fock state, two singly excited states, and a doubly excited state. VQE modifies the input state with the given parameters `theta1`

, `theta2`

and `theta3`

, and returns the estimated ground state energy for that given input state, in order to determine the variational bound of energy.

namespace Microsoft.Quantum.Chemistry.VQE { open Microsoft.Quantum.Core; open Microsoft.Quantum.Chemistry; open Microsoft.Quantum.Chemistry.JordanWigner; open Microsoft.Quantum.Chemistry.JordanWigner.VQE; open Microsoft.Quantum.Intrinsic; operation GetEnergyVQE (JWEncodedData: JordanWignerEncodingData, theta1: Double, theta2: Double, theta3: Double, nSamples: Int) : Double { let (nSpinOrbitals, fermionTermData, inputState, energyOffset) = JWEncodedData!; let (stateType, JWInputStates) = inputState; let inputStateParam = ( stateType, [ JordanWignerInputState((theta1, 0.0), [2, 0]), // singly-excited state JordanWignerInputState((theta2, 0.0), [3, 1]), // singly-excited state JordanWignerInputState((theta3, 0.0), [2, 3, 1, 0]), // doubly-excited state JWInputStates[0] // Hartree-Fock state from Broombridge file ] ); let JWEncodedDataParam = JordanWignerEncodingData( nSpinOrbitals, fermionTermData, inputState, energyOffset ); return EstimateEnergy( JWEncodedDataParam, nSamples ); } }

To compare this approach to the previous calculation of caffeine using RPE, we can estimate how many resources it will take to run this algorithm. Because it’s variational, let’s look at just the cost for one iteration (`nSamples=1`

):

In: from Microsoft.Quantum.Chemistry.VQE import GetEnergyVQE GetEnergyVQE.estimate_resources( JWEncodedData=encoded_data_caffeine, theta1=0.001, theta2=-0.001, theta3=0.001, nSamples=1 ) Out: { 'CNOT': 0, 'QubitClifford': 1440, 'R': 0, 'Measure': 3240, 'T': 0, 'Depth': 0, 'Width': 8, 'QubitCount': 8, 'BorrowedWidth': 0 }

Note that while the resources for a single run are much lower compared to RPE, this algorithm has a much higher total cost because we still need to multiply the numbers for gates and measurements above by the number of samples and optimization steps, as discussed in our recent prospects.

Let’s try out calculating the energy for a given trial state of the ground state of caffeine for a given initial set of parameters `theta1`

, `theta2`

and `theta3`

:

In: GetEnergyVQE.simulate( JWEncodedData=encoded_data_caffeine, theta1=0.001, theta2=-0.001, theta3=0.001, nSamples=10000000 ) Out: -627.6287520087537

To find the ground state energy, we need find the optimal values of `theta1`

, `theta2`

and `theta3`

at which the energy is minimized. Instead of doing a large scan over the entire parameter space, we run this quantum simulation using an optimizer. For that, we can use any optimization function that can minimize a cost function given a set of input parameters. Here, we will use `scipy.optimize`

:

from scipy.optimize import minimize def run_program(var_params, num_samples) -> float: # run parameterized quantum program for VQE algorithm theta1, theta2, theta3 = var_params return GetEnergyVQE.simulate( JWEncodedData=encoded_data_caffeine, theta1=theta1, theta2=theta2, theta3=theta3, nSamples=num_samples ) def VQE(initial_var_params, num_samples): """ Run VQE Optimization to find the optimal energy and the associated variational parameters """ opt_result = minimize( run_program, initial_var_params, args=(num_samples,), method="COBYLA", tol=0.000001, options={'disp': True, 'maxiter': 200,'rhobeg' : 0.05} ) if opt_result.success: print(opt_result.message) print(f"Result: {opt_result.fun} Ha") print(f"Number of evaluations: {opt_result.nfev}") print(f"Optimal parameters found: {opt_result.x}") return opt_result

We can then run this to find the ground state energy. To get an accurate result, let’s use 10 million samples:

In: VQE([0.001, -0.001, 0.001], 10000000) Optimization terminated successfully. Result: -627.6287829908172 Ha Number of evaluations: 39 Optimal parameters found: [ 0.05093427 -0.00092959 0.05098581]

This prints the and returns the optimization result returned by the optimizer. For a more detailed overview of the parameters that are returned by the minimize function, see the scipy.optimize documentation page.

Important to note here is that the energy estimate by VQE is not going to be as close to the exact energy that we simulated earlier with the RPE sample. This is mainly because we chose a fairly simple trial state. By choosing a more elaborate trial state we will be able to get a better estimate, but this would require us to use more qubits and gate operations in order to run the algorithm.

If this blog post has inspired you to develop quantum algorithms in Q#, we encourage you to get started with our MS Learn modules to get your machine set up to run quantum simulations on your own machine:

Create your first Q# program by using the Quantum Development Kit – Learn | Microsoft Docs

To get a refresher of the fundamental concepts of quantum computing, this MS Learn learning path might help you get started as well:

Quantum computing foundations – Learn | Microsoft Docs

If you prefer to get started with some hands-on samples that you can run directly including the one covered in this blog post, we recommend cloning our Quantum repo which contains more chemistry examples than the ones just mentioned in this blog post:

microsoft/Quantum: Microsoft Quantum Development Kit Samples (github.com)

Alternatively, launch the repo in Binder to can get started running algorithms via IQ# right away:

The Broombridge files and example code that were used in this blog post are part of the `qdk-python`

repo:

microsoft/qdk-python: Python packages for the Microsoft Quantum Development Kit (QDK) (github.com)

If you have any questions, please don’t hesitate to get in touch with us and other quantum developers using the comments to this blog post or the Q# community. Happy quantum developing!

The post Quantum developer tools for chemistry appeared first on Q# Blog.

]]>The post Inside the Quantum Katas, part 2: testing quantum programs appeared first on Q# Blog.

]]>In this blog post we will continue the deep dive into testing different types of quantum programming tasks.

Tasks that ask the learner to implement a given unitary transformation – an operation on qubits that changes their state – are frequently seen in the katas. Quantum oracles and more complicated operations such as quantum Fourier transform or quantum arithmetic are just a few examples that justify their popularity.

Verifying that the learner’s solution is correct can be done by comparing it to the reference implementation using the AssertOperationsEqualReferenced library operation. This operation relies on the Choi–Jamiołkowski isomorphism to reduce the comparison of two unitaries to a comparison of a quantum state to the all-zeros state. Let’s take a quick look at how it works for the small case of single-qubit unitaries (for unitaries acting on multiple qubits the principle is the same but the math is bulkier).

- We will start by preparing an entangled state |Φ⁺⟩ = 1/√2 (|00⟩ + |11⟩).
- Apply the learner’s solution that implements the unitary U to the second qubit:
1/√2 (|0⟩ ⊗ U|0⟩ + |1⟩ ⊗ U|1⟩) This state carries all information about the effects of the unitary on all basis states, and thus, all the information about the unitary itself (up to a global phase). - Now apply the adjoint of the reference implementation R to the second qubit:
1/√2 (|0⟩ ⊗ R†U|0⟩ + |1⟩ ⊗ R†U|1⟩) The trick turns out to be similar to the one we’ve seen when testing the state preparation tasks. If the unitaries R and U are the same, their effects on the state are going to cancel out, and we’ll get the state |Φ⁺⟩ with which we started. If the unitaries are different, their effects either on the |0⟩ state or on the |1⟩ state will not cancel out, and we’ll end up with a different state. - To check whether we ended up with the original state |Φ⁺⟩, we can use the same trick again: apply the adjoint of the routine used to prepare it from the |0⟩ state and compare the result to the |0⟩ state.

With all these steps hidden away in the library operation, the actual test code ends up very short. Here is the testing harness from the first task of the MultiQubitGates tutorial:

@Test("QuantumSimulator") operation TestCompoundGate () : Unit { AssertOperationsEqualReferenced(3, CompoundGate, CompoundGate_Reference); }

In the previous examples we’ve covered tasks that focused on practicing using quantum gates; now let’s learn more about the tasks that offer measurements practice.

The Measurements kata offers tasks which give the learner qubits in one of two or more possible orthogonal states (for example, |0⟩ or |1⟩) and ask to figure out which state it was. This type of task can be tested as follows:

- Pick one of the possible input states randomly.
- Prepare the qubits in this state and pass them to the solution.
- Compare the solution’s answer with the state we picked to see if it’s a match.
- Repeat the steps 1-3 several times to reduce the probability that the solution guessed the state accidentally. This also allows us to gather statistics on the incorrect guesses to help the learner identify their mistakes, such as confusing the indices of states returned or making randomized guesses instead of deterministic.

The testing harness complete with error tracking can get somewhat lengthy; you can find the complete example from the Measurements kata here.

This testing approach can be used for other types of tasks as well. The second part of the Measurements kata offers tasks in which the solution has to identify the state with a certain probability or without errors but with some “unknown state” verdicts allowed. A more recent DistinguishUnitaries kata asks the learner to figure out which of the two unitaries they are given by designing the right experiment.

Sometimes we care not only about the results produced by the solution but also about the operations used by it. Here are several examples of such tasks:

- The Deutsch-Jozsa algorithm example from part 1, in which we want to ascertain that the learner uses the quantum algorithm rather than the classical one, and the most reliable way to do this is to limit the number of times they can use the oracle.
- The random numbers generation tutorial prohibits the use of classical random number generation routines to make sure the learner uses the quantum approach to generating randomness.
- The task that asks the user to implement CNOT using joint measurements restricts the use of two-qubit gates, since otherwise calling CNOT or Controlled X would achieve the formal goal without making the point.

Some of these needs can be addressed by the library operation AllowAtMostNCallsCA. However, the Quantum Katas use a more sophisticated and more flexible approach: the CounterSimulator. It is a custom simulator built as an extension to the full state simulator provided with the QDK, and it counts various resources used during the “normal” program simulation. Developing a simulator with resource counting capabilities is out of scope for this blog post, but since it exists (and is shipped as part of the Microsoft.Quantum.Katas NuGet package), the testing harnesses can use its methods to get the necessary resource counts.

Here is the testing harness for the Deutsch-Jozsa algorithm which runs the algorithm on the given oracle, checks that its result is correct and then checks that the solution doesn’t overuse the oracle calls:

operation TestDJAlgorithm (N : Int, oracle : (Qubit[], Qubit) => Unit, expected : Bool, msg : String) : Unit { EqualityFactB(DJ_Algorithm(N, oracle), expected, msg); let nu = GetOracleCallsCount(oracle); Fact(nu <= 1, $"You are allowed to call the oracle at most once, and you called it {nu} times"); }

Similarly, sometimes we care about the number of auxiliary qubits allocated by the solution. The simplest examples are tasks that ask the learner to implement a phase oracle for a certain function. If the task aims to teach phase manipulation, it might prohibit the solution allocating extra qubits to render implementing a marking oracle and then using the phase kickback trick impossible.

What will the testing harness look like in this case? We can validate that the solution implements the right unitary using the AssertOperationsEqualReferenced operation from the example 1. On top of that, we can use another library operation, AllowAtMostNQubits, to check that AssertOperationsEqualReferenced allocates exactly 2N qubits, where N is the number of qubits on which the oracle acts. (Why 2N? Remember that AssertOperationsEqualReferenced uses 2N qubits to compare the unitaries that act on N qubits. If the reference solution does not allocate extra qubits, any qubits allocated on top of 2N must come from the learner’s solution!)

Here is the testing harness used for the task:

@Test("QuantumSimulator") operation TestPhaseOracle () : Unit { let N = 3; within { AllowAtMostNQubits(2*N, "You are not allowed to allocate extra qubits"); } apply { AssertOperationsEqualReferenced(N, PhaseOracle, PhaseOracle_Reference); } }

These testing patterns are the ones most frequently used in the Quantum Katas. There are plenty of one-off tasks that require more elaborate testing logic (the whole counting multi-qubit gates functionality of the CounterSimulator is only used in one task!), but these should help you get started with testing your own quantum code.

If you’re looking for more advanced scenarios of code verification, see the paper “A Resource Estimation and Verification Workflow in Q#” by Mathias Soeken et al.

The post Inside the Quantum Katas, part 2: testing quantum programs appeared first on Q# Blog.

]]>You can see all of the release notes for the year here.

Thinking of You

2020 was a year like no other.

Life was dominated by the COVID-19 virus and the measures taken around the world to try and control its spread.

The post Three Years of Q# appeared first on Q# Blog.

]]>You can see all of the release notes for the year here.

2020 was a year like no other. Life was dominated by the COVID-19 virus and the measures taken around the world to try and control its spread.

I, and the entire Microsoft Quantum team, hope that you and those close to you have weathered the pandemic safely, and wish you continued health and safety in the coming year.

Perhaps our primary theme for this past year has been opening up Q# to more community involvement.

Our first release of Year 3 added support for compiler extensions, which make it easier for anyone to add new functionality to the Q# compiler. We are very excited about this feature; we really want to make it as easy as possible for the community to experiment with Q#.

In September we launched the Q# Language Design GitHub repository. This site provides a forum for discussing proposed language features and defines a process for proposing new features and for evaluating and approving proposals. It serves a similar purpose for the Q# standard library APIs. We have already collected several issues from the community that will help guide the future evolution of the language. We hope to continue to get this sort of feedback both as new issues and also as feedback on proposed features while they’re being discussed.

Also in September, we launched QIR, our quantum intermediate representation. QIR is language- and platform-independent; it supports Q#, but it is completely general. QIR is based on the popular LLVM open source compiler framework, so it is immediately compatible with the many LLVM-based tools available, such as the clang compiler. There are already teams in several national laboratories using QIR to bridge Q# to classical and quantum platforms.

This past year saw continued growth in community contribution to Q# development, which we greatly appreciate. We added our first team-external maintainer to one of our core repositories, the Quantum Katas. Our Hacktoberfest participation generated about 30 contributions to our repositories, among a total of about 175 community contributions for the full year.

We are very proud to announce that the Unitary Fund made grants to two Q#-based projects: QRAM and QAOA.

Finally, we ran our third Q# coding contest this past summer. It attracted 657 participants, 591 of whom solved at least one problem.

We added a lot of library functionality in 2020. Perhaps the most exciting addition was the quantum machine learning library we rolled out in February. You can see it in use in this tutorial.

Machine learning, of course, is one of the hottest topics in modern computer science. Every large software company is investing heavily in machine learning and artificial intelligence, and many people expect that quantum computing will lead to better machine learning algorithms. While there haven’t been any demonstrations yet of quantum machine learning algorithms that significantly outperform classical ones, this is a very active area of research. We’re happy to provide a “starter kit” to help advance this field.

Based on user feedback we’ve been working on overall performance. Recent releases have made significant improvements to the compiler and simulator performance. We continue to work in this area, and there should be continued improvement over the coming year.

Our last, but far from least, theme for 2020 was improved usability. We made a number of usability improvements to the Q# standard libraries, added new samples, and added some new testing and debugging features. We added the ability to create stand-alone Q# projects that don’t require a driver in another language.

One particular focus was on making our Jupyter notebook integration easier to use and more powerful. We added multiple new features there, especially around visualization. We also made it easier to use IQ# with other Python tools such as NumPy.

This post is part of the Q# Advent Calendar 2020. Follow the calendar for other great posts!

The post Three Years of Q# appeared first on Q# Blog.

]]>The post Emulation in Q# appeared first on Q# Blog.

]]>The first technique employs intrinsic functions. It can be used to implement a Q# function using a .NET language, for example C#. This is particularly useful when the required library functionality is not available in Q#. Let’s consider the following example, typical for this season. We often find ourselves in need of the number of the remaining days until Christmas as a value in our Q# operation. This value can be used as the secret shift in the hidden shift algorithm or as the special element in a Grover search. We cannot retrieve the current date in Q#, and therefore we have to provide this function as an intrinsic:

function DaysUntilChristmas() : Int { body intrinsic; }

This Q# code gets translated into a partial C# class called `DaysUntilChristmas`

.
We can add the implementation by creating a nested class called `Native`

that
derives from `DaysUntilChristmas`

. In its constructor this class accepts an instance `m`

of type `IOperationFactory`

, which is the base class to
all simulators. Therefore, `m`

holds the simulator object for which the
function is called. This will enable us to perform simulator-dependent code.
We’ll use this variable when describing the second technique, however, in this
example we compute the same function independent of the simulator.

public partial class DaysUntilChristmas { public class Native : DaysUntilChristmas { public Native(IOperationFactory m) : base(m) {} // can be adjusted (e.g., 1/7, 1/6, 1/19, ...) private static int ChristmasMonth => 12; private static int ChristmasDay => 25; // C# function with matching signature private long DaysUntilChristmasFunction(QVoid input) { var today = DateTime.Today; var christmas = new DateTime(today.Year, ChristmasMonth, ChristmasDay); // make sure the next Christmas is today or in the future if (christmas < today) christmas = christmas.AddYears(1); // return difference in days return (christmas - today).Days; } // Override __Body__ property to use C# function public override Func__Body__ => DaysUntilChristmasFunction; } }

The function implementation is provided in terms of the `__Body__`

property,
which is of type `Func<__In__, __Out__>`

, where `__In__`

is the type of the input
argument tuple in the Q# function and `__Out__`

is the type of the output
argument tuple. In this case, there are no input arguments,
represented by the empty tuple type `QVoid`

, and there is a single output
argument of Q# type `Int`

, which corresponds to the C# type `long`

(= `Int64`

).

We can use a similar technique to replace an existing function with an
alternative one. It would be nice to make Q#’s `Message`

outputs a little more
festive this month. For this purpose, we implement an intrinsic function called
`ChristmasMessage`

:

function ChristmasMessage(msg : String) : Unit { body intrinsic; }

The implementation is provided in C# and it prefixes each message with Santa’s way of expressing his happiness and joy.

public partial class ChristmasMessage { public class Native : ChristmasMessage { private readonly IOperationFactory simulator; public Native(IOperationFactory m) : base(m) { simulator = m; } private QVoid ChristmasMessageFunction(string message) { if (simulator is ToffoliSimulator) { WriteLine(message); } else { WriteLine($"Ho ho ho: {message}"); } return QVoid.Instance; } public override Func__Body__ => ChristmasMessageFunction; } }

Note that we do not override the behavior when using the `ToffoliSimulator`

,
since the Toffoli simulator does not support the `H`

in *Ho ho ho*.

Instead of replacing all occurrences of `Message`

in our Q# programs by hand, we
wish to do this automatically and hide the existence of the `ChristmasMessage`

from our users. When constructing a simulator instance in a C# host program, we
can use the `Register`

method to replace an existing function with an
alternative one.

var simulator = new QuantumSimulator(); simulator.Register(typeof(Message), typeof(ChristmasMessage), typeof(ICallable));

The first parameter is the type of the existing function, in this case
`Message`

, the second parameter is the type of the replacement, in this case
`ChristmasMessage`

, and the third parameter is the type of either `ICallable`

,
`IAdjointable`

, `IControllable`

, or `IUnitary`

. For functions and operations
that are neither adjoint nor controlled, use `ICallable`

. For operations that
are marked `Adj`

but not `Ctl`

, use `IAdjointable`

, for those marked `Ctl`

but
not `Adj`

, use `IControllable`

, and if they have both, use `IUnitary`

.

It’s worth to note that we couldn’t just have implemented `ChristmasMessage`

by
calling `Message`

inside and then use `Register`

for the replacement. This
would have lead to an infinite recursive loop, since the `Message`

call inside
`ChristmasMessage`

would also be replaced.

The same technique can be used to replace one Q# operation by another Q# operation, the replacement operation doesn’t need to be implemented in C#. Consider the following operation that swaps two qubits using three CNOTs:

operation SwapWithCNOTs(a : Qubit, b : Qubit) is Adj+Ctl { CNOT(a, b); CNOT(b, a); CNOT(a, b); }

To replace the `SWAP`

operation in the `Microsoft.Quantum.Intrinsic`

namespace,
we can simply call `Register`

on the simulator like this:

simulator.Register(typeof(SWAP), typeof(SwapWithCNOTs), typeof(IUnitary));

The emulation technique was demonstrated for Q# functions in this post, but it
applies similarly to Q# operations as well. However, depending on the supported
functors (such as `Adj`

and `Ctl`

), operations for `__AdjointBody__`

,
`__ControlledBody__`

, and `__AdjointControlledBody__`

might also need to be implemented.

The technique is used in several places in the Q# and QDK code base. Some examples include:

- Many functions in the
`Microsoft.Quantum.Math`

namespace. - Speeding up full state simulation for quantum oracles by applying the permutation directly to the state vector.
- A custom gate counting simulator in the Quantum Katas that keeps track of gate and qubit resources to power the testing harnesses used to validate the learner’s solutions.
- Replacing
`ApplyAnd`

and`ApplyLowDepthAnd`

with`CCNOT`

when used with the Toffoli simulator.

The complete code for the project can be found in this gist.

It’s `DaysUntilChristmas()`

days until Christmas, ```
ChristmasMessage("Happy
holidays!")
```

.

The post Emulation in Q# appeared first on Q# Blog.

]]>If you’re reading this blog post, you probably have heard of the Quantum Katas – our collection of tutorials and programming exercises that help one learn quantum computing via quantum programming.

The post Inside the Quantum Katas, part 1 appeared first on Q# Blog.

]]>If you’re reading this blog post, you probably have heard of the Quantum Katas – our collection of tutorials and programming exercises that help one learn quantum computing via quantum programming. (If you haven’t, check them out – I’ve heard great feedback about them )

The Katas are about two and a half years old, and I’ve written about them before once or twice – from the first overview of the project and the summary of its first year in public to its part in this year’s Hacktoberfest celebration (we got 23 pull requests from 11 different folks, 8 of them first-time contributors!)

Oddly enough, I’ve never written about the internal workings of the katas or their most important component – the testing harnesses that provide the learner immediate feedback on their solutions. Testing quantum programs is an interesting topic, very different from testing classical code in some respects and quite similar to it in others. Let’s see how we build the Quantum Katas and how we test them.

Each kata is a sequence of individual tasks, and each task consists of several pieces working in concert.

- The task.

This is the “frontend” of the task, the part where the user spends most of their time. It includes the description of the task (what needs to be accomplished, the format of inputs and outputs, examples and any restrictions imposed on the solution) and the signature of the Q# operation that the learner needs to implement.

A typical kata will have two “frontends” – in the`Tasks.qs`

file (used when solving the kata in Visual Studio or VS Code) and in the Jupyter Notebook. The task description and, most importantly, the operation signature of the task should always match in both cases, though the Jupyter Notebook “frontend” certainly looks much fancier! - The reference solution.

`ReferenceImplementation.qs`

file contains the “reference” solutions to all tasks – correct solutions to the tasks that will pass the tests. Sometimes these solutions play a significant role in the testing of the learner’s code, and one can always turn to them to get an idea about the expected approach to the task. That last goal, though, is often better served by the workbooks – the worked-out explanations of the tasks and their implementation in code that are included in many katas. - The testing harness.

Finally,`Tests.qs`

file contains the code that verifies whether the learner’s code is correct. It is implemented as a collection of unit tests, one per task, that pass if the learner filled in the right code to solve the task and fail otherwise. (This means that when you start solving the kata in VS or VS Code, all tests are failing – a somewhat scary set up!)

The Jupyter Notebook “frontend” doesn’t support unit tests, so the testing harness is invoked using the`%kata`

magic command included in the code cell that contains the task operation.

The most important part of developing a new task is creating the testing harness for it. When we consider the ways to test a solution, we follow one main principle:

In other words, we test whether the solution accomplishes the given task, not the exact path it takes to do that.

Consider, for example, the following task: given a pair of qubits in the |00⟩ state, prepare one of the Bell states |Φ⁻⟩ = 1/√2 (|00⟩ – |11⟩). There are a lot of ways to do this – start by preparing a different Bell state |Φ⁺⟩ = 1/√2 (|00⟩ + |11⟩) and then adjust the relative phase of the second term by applying the Z gate to one of the qubits, or apply an X gate to one of the qubits before applying the Hadamard gate to it and using it as a control in CNOT gate – the possibilities are endless! At the same time we don’t really care which path to the solution the learner takes – the idea of the task is to practice using Pauli gates and the CNOT gate to prepare entangled states, and if the end result is the right superposition state, the task achieved its goal.

Of course, sometimes the goals of the task are more sophisticated than this. The first time we hosted a workshop using the prototype of the DeutschJozsaAlgorithm kata, one of the attendees went ahead and implemented the classical solution to the problem solved by the Deutsch-Jozsa algorithm (figuring out whether the given function is constant or balanced), applying the quantum oracle to basis states to evaluate the classical function. This is a valid classical approach (and later we added it as a separate task to the ExploringDeutschJozsaAlgorithm tutorial), but not the quantum algorithm we’re looking for! We had to add an extra check to count the number of times the given oracle is applied in the learner’s solution, and if it is more than once, fail the test.

Over the years we have accumulated quite a box of tricks for testing different kinds of programming tasks, and I’ll share some of them in the second part of this post. For now, let’s take a look at the simplest example (that is also historically the first type of tasks developed for the Katas) – testing a state preparation task.

Let’s use our Bell state preparation task again: given a pair of qubits in the |00⟩ state, prepare the state |Φ⁻⟩ = 1/√2 (|00⟩ – |11⟩).

First, how does the task signature look like? We want the task to take a pair of qubits as a parameter and have no return – the result of the task is the change in the qubits’ state. The Q# signature that matches this is

operation PrepareBellStatePhiMinus (qs : Qubit[]) : Unit { // ... }

This is it! In the task we leave the operation body blank and mark the part that needs to be filled by the learner with a `// ...`

comment.

To get the reference solution, we just copy the task signature, rename the operation and fill in the code that solves the task.

operation PrepareBellStatePhiMinus_Reference (qs : Qubit[]) : Unit { H(qs[0]); CNOT(qs[0], qs[1]); Z(qs[0]); }

Now, how can we test this kind of a task?

Remember that Q# doesn’t give us direct programmatic access to the amplitudes of the quantum state vector, since that doesn’t match the physical reality of a quantum-mechanical system. Instead, it offers a variety of operations in the Microsoft.Quantum.Diagnostics namespace that can only be applied when running the code on a simulator – which is the case for the Katas – and allow to provide diagnostics on the simulator and to check various assertions about its state. In our case we’ll run the test on the full state simulator and use AssertAllZero operation which passes if all qubits of the given array are in the |0⟩ state and fails otherwise.

At this point an attentive reader should ask “Wait, we are given the |00⟩ state, we’re not trying to prepare it, are we?” We’ll need to do one more step before we can use this assertion to implement our test, and this step involves the reference solution for the task and the very convenient ability of Q# compiler to generate adjoints of quantum operations automatically.

More specifically, we have the learner’s solution that implements a transformation U, and we need to check whether it transforms the initial |00⟩ state to the required state |Φ⁻⟩:

We also know that our reference solution R performs this transformation correctly:

Let’s apply adjoint of our reference solution R† to both parts of the check we want to do:

We see that if we start with the |00⟩ state and apply first the learner’s solution and then the adjoint of the reference solution, we’ll end up with the |00⟩ state again if and only if the learner’s solution did indeed prepare the |Φ⁻⟩ state. Importantly, the results of this check don’t depend on the path the solution took to arrive to the required state.

The code implementation of this test ends up being shorter than the explanation of the logic behind it: once we add “is Adj” to the signature of the reference implementation to enable automatic adjoint generation,

@Test("QuantumSimulator") operation TestPrepareBellStatePhiMinus () : Unit { use qs = Qubit[2]; PrepareBellStatePhiMinus(qs); Adjoint PrepareBellStatePhiMinus_Reference(qs); AssertAllZero(qs); }

This testing harness can be improved further. For example, the error message it produces, “Qubit in invalid state.”, is not very helpful for the learner. The Superposition kata makes an extra effort to output the desired superposition state and the state prepared by the learner’s solution (using another convenient diagnostic operation DumpMachine) before comparing these states.

In part 2 of this blog post we’ll take a look at other types of programming tasks offered in the Quantum Katas and the tools we use to test them. Stay tuned!

The post Inside the Quantum Katas, part 1 appeared first on Q# Blog.

]]>The post Interning at Microsoft Quantum – 2021 appeared first on Q# Blog.

]]>This summers’ internships turned out to be quite different from what we planned for when we sent out offers to our interns in February. We were looking forward to a perfectly regular summer, the interns flying in from all over the world to join us in Redmond… And then COVID happened, which, among everything else, meant that there would be no travel and no in-person interactions with the interns. Fortunately, Microsoft has been able to save most internships by switching them to virtual format. But that posed a new set of challenges: how to make a virtual experience as immersive, educational, and enjoyable as an in-person internship would have been?

The work on the projects looked very similar to a regular year, with the addition of a fair number of extra meetings. Admittedly, it is a lot easier to catch your mentor online in a scheduled one-on-one than in an impromptu meeting like one would normally do when sharing an office. The interns’ project presentations were not changed much compared to last year as well, with other interns and employees stopping by to listen in a Teams meeting instead of a meeting room.

Social and networking events proved to be more of a challenge. Some of them, like the OneWeek Hackathon and Intern Puzzle Day, switched to online format relatively easily – a lot of the experience in these events depends on one’s team, and both offered great ways to find a good team to hack or to solve puzzles with. The “Introduction to quantum computing” workshop hosted by our team for the interns made the transition nicely as well, attracting over 700 interns from across the company and ending up being one of the favorite intern events throughout the summer. The main downside of the newly online events format? No new cool photos to commemorate them!

Other events required some ingenuity to orchestrate. How do you replace bumping into a fellow intern at the watercooler or joining an employee from a different part of the company for a chat at lunchtime? Our team organized multiple events to attempt to replicate or replace various parts of the experience – from “open office” times with team leaders and weekly brown bags where team members talked about their work to a Q# learners club to weekly online “board game nights” and an occasional virtual escape room. Some of these opportunities were only introduced this year, and we hope that helped to make the virtual experience both useful and memorable!

In the upcoming season we will be offering three different types of internships:

- Research internships are the most traditional of our internships, targeting graduate students pursuing a PhD in quantum computing. (Read more about the past research internships in the last year’s announcement.)
- In 2019 we introduced quantum programming internships, focusing on software projects in Quantum Development Kit or Azure Quantum. I hope to share more information about our interns’ projects later, as they are polished up and/or released to the public. Here is a sneak peek at the project two of our interns worked on – new %trace and %debug commands for Q# Jupyter Notebooks. (You can also read more about the previous quantum programming internships in last year’s announcement.)
- In the new program management internship the intern will work with our Azure customers to design Azure Quantum to help them achieve their goals.

Regardless of the kind of projects our interns will work on, one thing I’m certain about – this will be an awesome experience for them!

Does this sound like a great way to spend your summer? Apply to our open internship positions today! Application deadline is January 8

^{th}, 2021.

**Update (November 23 ^{rd})**: Per the announcement, our 2021 Intern Program will be fully virtual in 2021. As was the case last season, our program is able to support internships for students located in the US and Canada.

The post Interning at Microsoft Quantum – 2021 appeared first on Q# Blog.

]]>The post Q# Advent Calendar 2020 appeared first on Q# Blog.

]]>The rules are simple:

- Reserve a slot by leaving a comment on this post. (You can also tweet about it, but you’ll have to mention @tcNickolas to make sure we’ve seen it!) The slots are assigned on the first come, first serve basis. You do not have to announce the topic of your blog post until you’re ready to publish it, but we’d really love to hear it beforehand. (This also helps other bloggers to pick a topic that is not too close to the ones already covered.)
- Prepare a blog post (in English) about Q#, cool project you’ve done in Q#, learning Q#, teaching Q#, using Q# for research, tools for working with Q#… You got the idea.* Don’t forget to check out the previous calendars for inspiration!
- Publish your blog post on your assigned date. Don’t forget to link back to the Q# Advent Calendar from your post, so that your readers can find the entire advent.
- Leave the link to your blog post in a comment to this post, and we’ll add it to the calendar. If you share a link to your post on Twitter, use hashtags #qsharp and #QsAdvent.

**Q# Advent Calendar accepts only original content.*

Looking forward to reading your Q# stories!

The post Q# Advent Calendar 2020 appeared first on Q# Blog.

]]>The post Celebrating our open source community with Hacktoberfest appeared first on Q# Blog.

]]>The Quantum Development Kit (QDK) includes a lot of components: from the samples and libraries that were released as open source back in 2017, to the compiler and runtime open sourced in 2019, to the newest addition to the roster – Q# language repository that hosts language design discussions. (Here is an excellent overview of the components and open source repositories that are part of the QDK.)

As the footprint of our open source code grew, so did the community around it. The most active of our open source repositories – the collection of tutorials and programming exercises on quantum computing called the Quantum Katas – has over a hundred contributors, only around 20% of them from Microsoft Quantum team!

Some of our contributors have been with us for over a year; it doesn’t seem like a long time, until you remember that the QDK itself is less than three years old! Today I am delighted to recognize one of our most dedicated contributors, Vincent van Wingerden, and to promote him to the role of maintainer of the Quantum Katas. In his day job Vincent is a technical architect at Microsoft for Data & AI, helping people create the best possible data solutions on Azure. He started contributing to the Quantum Katas in November 2019, and since then he did a lot of work on the workbooks – the detailed explanations of the solutions to the programming tasks offered in the tutorials. In fact, Vincent is the second most active contributor to the Katas – and now he has a chance to experience the other side of the open source, helping others to do their first contributions.

Over the past year we hosted several internal Hackathons, including a Hacktoberfest celebration at the Microsoft Garage.

This October, in-person meetups are not really an option, so we decided to take the experience online – and open it to everybody worldwide!

One of the most important things in getting started is finding just the right thing to work on. People new to GitHub need something very simple, so that they can focus on mastering the contribution process itself – it is not complicated but can be baffling when going though it for the first time. Experienced GitHub users might pick a slightly more complicated issue to learn more about quantum computing or compilers. And regular contributors can challenge themselves to do an advanced project, though they are not shy about doing it any time of year!

With this in mind, we selected a variety of issues spanning nearly all areas in the QDK and a broad range of complexity, from small writing tasks to fixing bugs and developing small features.

- The Quantum Katas issues.
- Q# samples issues.
- Q# libraries issues.
- Q# compiler issues.
- Documentation issues.

You can also check out our contribution guide and browse all our repositories to see if there is something not on this list that piques your curiosity.

Ready to start? Here are three easy steps:

- Register for Hacktoberfest. Once you send 4 pull requests to GitHub repositories this October, you’ll be eligible for their “tee or tree” reward – a Hacktoberfest T-shirt or a tree planted on your behalf.
- Join our kick-off call on October 8th to meet the maintainers of our repositories and learn about the areas you can contribute to.
- Head to our open source repositories, pick an issue with Hacktoberfest label and get started!

We’ll be there to answer your questions and guide you through the contributions.

Happy hacking!

The post Celebrating our open source community with Hacktoberfest appeared first on Q# Blog.

]]>QIR is a new Microsoft-developed intermediate representation for quantum programs. It is based on the popular open-source LLVM intermediate language. QIR specifies a set of rules for representing quantum constructs in LLVM. It does not require any extensions or modifications to LLVM.

The post Introducing Quantum Intermediate Representation (QIR) appeared first on Q# Blog.

]]>QIR is a new Microsoft-developed intermediate representation for quantum programs. It is based on the popular open-source LLVM intermediate language. QIR specifies a set of rules for representing quantum constructs in LLVM. It does not require any extensions or modifications to LLVM.

QIR is intended to serve as a common interface between many languages and target quantum computation platforms. Thus, while it supports Q#, QIR is not specific to Q#: any programming language for gate-based quantum computing can be represented in QIR. Similarly, QIR is hardware-agnostic: it does not specify a quantum instruction or gate set, leaving that to the target computing environment.

As quantum computing capabilities mature, we expect most large-scale quantum applications will take full advantage of both classical and quantum computing resources working together. LLVM provides QIR with full capabilities for describing rich classical computation fully integrated with quantum computation. Using LLVM also facilitates integration with the many classical languages and tools which are already supported by the LLVM tool chain. It also promotes the development of common language- and backend-independent optimizations and code transformations, based on a well-known and robust open-source framework.

In the coming years, we expect there to be exciting advances in how classical and quantum computations can interact at the hardware level. With QIR we intend to provide a single representation that can be used for both today’s restricted capabilities and the more powerful systems of the future. This will allow the community to experiment with and develop optimizations and code transformations that work today and that will remain useful tomorrow.

A common pattern in compilers is to start by compiling the source language into an intermediate representation. This intermediate form is typically designed to allow many different source languages to be represented. While still in the intermediate representation, the code can be optimized and transformed. Finally, once the actual target execution platform is known, the intermediate representation can be compiled to actual executable code.

This approach allows many source languages to share a common set of optimizers and executable generators. It also makes it easy to compile a single source language for many different targets. The intermediate representation provides a common platform that can be shared across many sources and targets and allows a great deal of re-use in compiler machinery.

Since QIR is based on LLVM, QIR looks like LLVM.

For example, here is some simple Q# code to generate a Bell pair:

```
// Assumes that qb1 and qb2 are already in the |0> state
operation BellPair(qb1 : Qubit, qb2 : Qubit) : Unit
{
H(qb1);
CNOT(qb1, qb2);
}
```

When compiled to QIR, this becomes:

```
define void @BellPair__body(%Qubit* %qb1, %Qubit* %qb2) {
entry:
call void @__quantum__qis__h(%Qubit* %qb1)
call void @__quantum__qis__cnot(%Qubit* %qb1, %Qubit* %qb2)
ret void
}
```

In this snippet, a few QIR features are apparent:

- Operations in Q# (or any other quantum programming language) are represented by LLVM functions.
- LLVM functions whose names start with
`__quantum__qis__`

are reserved to represent operations in the quantum instruction set being used. - Qubits are represented as pointers to a named opaque structure type,
`%Qubit`

.

While the QIR for this trivial sample is very simple, QIR inherits all of the capabilities of LLVM to express loops, conditionals, and other complex control flow. QIR also inherits LLVM’s ability to express arbitrary classical computation.

One application enabled by QIR is to use the clang compiler to compile QIR into executable machine code for a classical target. This provides an easy path to building a simulator in C or C++ by implementing the quantum instruction set functions mentioned above.

Another application is to use the standard LLVM “pass” infrastructure to write quantum optimizers that operate on QIR. The source- and target-independent approach of QIR allows optimizations to be used with many different computation languages and computing platforms.

QIR has been shared with some partners already to get early feedback. For instance, Oak Ridge National Laboratory’s Quantum Computer Scientist and XACC Project Alex McCaskey says “ORNL is working closely with the Microsoft quantum compiler team to enable compilation of high-level Q# programs to the diverse set of OLCF quantum hardware platforms via integration with the XACC quantum programming framework.”

Today we’ve rolled out two QIR-related components:

- In the new Q# language repository, the draft QIR Specification is posted here.
- In the main Q# compiler repository, we’ve posted a compiler extension that generates QIR from Q#. Directions for using this tool are here.

Comments and suggestions on the draft QIR specification are welcome. Please post them as issues in the Q# language repository using the appropriate template.

If you build an LLVM pass or other tool that works with QIR, we’d love to hear about it! Please submit a pull request to the list page with a description of your project and a pointer.

The post Introducing Quantum Intermediate Representation (QIR) appeared first on Q# Blog.

]]>