Skip to content

v1.31

Choose a tag to compare

@billti billti released this 30 Jul 23:02
· 129 commits to main since this release
7d03e9c

Below are some of the highlights for the 1.31 release of the QDK.

Break & Continue

With this release, we have added support for the break and continue keywords to Q# and OpenQASM. This doesn't unlock any new runtime capabilities (as equivalent logic is expressible with existing loop and conditional constructs) but it does allow for much more concise and natural-looking code. For example in OpenQASM,

int[32] i = 0;

while (i < 10) {
    i += 1;
    // continue to the next loop iteration
    if (i == 2) {
        continue;
    }

    // some program

    // break out of loop
    if (i == 4) {
        break;
    }

    // more program
}

And in Q#,

operation Foo(q : Qubit[], stopAt : Int) : Unit {
    let n = Length(q);

    // Break and continue act on the innermost enclosing loop body
    // They can also appear in while and repeat bodies.
    for i in 1..n-2 {
        if i == stopAt {
            break;
        }
        if i % 2 == 0 {
            continue;
        }
        CX(q[0], q[i+1]);
    }
}

Running Q# tests from Python

Q# supports writing unit tests (as operations annotated with @Test). Previously, these were only runnable within the VS Code UI. Now you can use the qdk.test_utils.run_tests Python API to run all unit tests in your Q# package.

from qdk import qsharp
from qdk.test_utils import run_tests

qsharp.eval("""
import Std.Diagnostics.Fact;

@Test()
operation MyTest() : Unit {
    Fact(2 + 2 == 4, "assertion failed");
}
""")

run_tests()

Compile-time configuration

You can now specify a compile-time configuration (as a Python dictionary passed to qsharp.init or the qdk.Context constructor) and access it in Q# code using Std.Core.ConfigValue. Calls to Std.Core.ConfigValue will be replaced with the provided values at compilation time.

from qdk import qsharp, code

qsharp.init(qdk_config={"size": 10, "angle": 2.0})

qsharp.eval("""
import Std.Core.ConfigValue;

operation Foo() : Result[] {
    let size = ConfigValue("size", 1);
    let angle = ConfigValue("angle", 0.0);

    use qs = Qubit[size];

    for q in qs {
        Rx(angle, q);
    }
    MResetEachZ(qs)
}
""")

code.Foo()

See the https://github.com/microsoft/qdk/tree/main/source/qdk_package#configuration-map documentation for more details.

New Arithmetic library

A new library for advanced quantum arithmetic operations has been added. The library is available at https://github.com/microsoft/qdk/tree/main/library/arithmetic, and can be used by Q# projects as outlined in https://learn.microsoft.com/en-us/azure/quantum/how-to-work-with-qsharp-projects#configure-the-manifest-files.

Determine if running under Resource Estimation

You can now determine whether code is being executed in resource estimation mode via the new Std.ResourceEstimation.IsResourceEstimating API. This can be useful if you want different behavior for resource estimation versus running code on a simulator or quantum hardware.

For example, if you have a loop, you can use Std.ResourceEstimation.RepeatEstimates in resource estimation mode, and a for loop otherwise.

Classical arithmetic functions

When working on arithmetic algorithms, it can be useful to define an operation that applies a function to a quantum register without implementing it.

Now you can do this in Q# using Std.ArithmeticTestUtils.ApplyClassicalFunction. It takes an n-qubit quantum register and a Q# function f : (BigInt) -> BigInt that represents a bijection on 0..2^n-1. The effect of this operation is equivalent to applying a unitary operation that maps |x> to |f(x)>.

We also provide a multi-register version (Std.ArithmeticTestUtils.ApplyClassicalFunctionN).

For example, you can represent in-place addition (equivalent to Std.Arithmetic.IncByLE) as follows:

import Std.ArithmeticTestUtils.ApplyClassicalFunctionN;
operation IncByLE(xs : Qubit[], ys : Qubit[]) : Unit is Ctl {
    let mod = 1L << Length(ys);
    ApplyClassicalFunctionN(a -> [a[0], (a[0]+a[1])%mod], [xs, ys]);
}

Arithmetic test helpers

When writing tests for arithmetic operations, we typically allocate registers, write inputs to them, apply an operation, and read the outputs. We added a helper Std.ArithmeticTestUtils.TestArithmeticOp to do all that, which can be used in Q# unit tests.

We also added a convenient Python wrapper around TestArithmeticOp, called ArithmeticOpTester, that allows you to write unit tests for arithmetic operations in Python. For example, this is how to write a test for Std.Arithmetic.IncByLE that checks this operation on 5 random inputs:

import random
from qdk.test_utils import ArithmeticOpTester
n = 10
tester = ArithmeticOpTester("Std.Arithmetic.IncByLE", [n, n])
for _ in range(5):
    x, y = random.randint(0, 2**n - 1), random.randint(0, 2**n - 1)
    assert tester.run([x, y]) == [x, (x + y) % (2**n)]

This feature is intended for developing and testing quantum algorithms and is currently supported only by the sparse simulator.

Other notable changes

New Contributors

Full Changelog: v1.30.0...v1.31.0