Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotate conditional compilation for fixed_point so it compiles in all profiles #2156

Merged
merged 5 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions library/fixed_point/src/Facts.qs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Licensed under the MIT License.

import Types.FixedPoint;
import Std.Arrays.IsEmpty, Std.Arrays.Rest;
import Std.Diagnostics.Fact, Std.Diagnostics.CheckAllZero;
import Std.Diagnostics.Fact;
import Std.Arrays.IsEmpty, Std.Arrays.Rest, Std.Arrays.Unzipped;

/// # Summary
/// Asserts that a quantum fixed-point number is
Expand All @@ -12,7 +12,9 @@ import Std.Diagnostics.Fact, Std.Diagnostics.CheckAllZero;
/// # Description
/// This assertion succeeds when all qubits are in state $\ket{0}$,
/// representing that the register encodes the fixed-point number $0.0$.
@Config(Unrestricted)
operation AssertAllZeroFxP(fp : FixedPoint) : Unit {
import Std.Diagnostics.CheckAllZero;
Fact(CheckAllZero(fp::Register), "Quantum fixed-point number was not zero.");
}

Expand All @@ -25,6 +27,7 @@ operation AssertAllZeroFxP(fp : FixedPoint) : Unit {
/// Array of quantum fixed-point numbers that will be checked for
/// compatibility (using assertions).
function AssertFormatsAreIdenticalFxP(fixedPoints : FixedPoint[]) : Unit {

if IsEmpty(fixedPoints) {
return ();
}
Expand Down
8 changes: 7 additions & 1 deletion library/fixed_point/src/Main.qs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

export Init.PrepareFxP as PrepareFxP, Measurement.MeasureFxP as MeasureFxP, Reciprocal.ComputeReciprocalFxP as ComputeReciprocalFxP, Types.FixedPoint as FixedPoint;
export Init.PrepareFxP as PrepareFxP, Types.FixedPoint as FixedPoint;

@Config(Unrestricted)
export Reciprocal.ComputeReciprocalFxP as ComputeReciprocalFxP;

@Config(FloatingPointComputations)
export Measurement.MeasureFxP as MeasureFxP;
1 change: 1 addition & 0 deletions library/fixed_point/src/Measurement.qs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Std.Convert.ResultArrayAsBoolArray;
/// # Input
/// ## fp
/// Fixed-point number to measure.
@Config(FloatingPointComputations)
operation MeasureFxP(fp : FixedPoint) : Double {
let measurements = MResetEachZ(fp::Register);
let bits = ResultArrayAsBoolArray(measurements);
Expand Down
13 changes: 10 additions & 3 deletions library/fixed_point/src/Operations.qs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

import Types.FixedPoint;
import Init.PrepareFxP;
import Facts.AssertPointPositionsIdenticalFxP, Facts.AssertFormatsAreIdenticalFxP, Facts.AssertAllZeroFxP;
import Operations.AddFxP;
import Signed.Operations.Invert2sSI, Signed.Operations.MultiplySI, Signed.Operations.SquareSI;
import Facts.AssertPointPositionsIdenticalFxP;
import Std.Arrays.Zipped;
import Std.Arithmetic.RippleCarryTTKIncByLE;

Expand All @@ -17,6 +18,7 @@ import Std.Arithmetic.RippleCarryTTKIncByLE;
/// ## fp
/// Fixed-point number to which the constant will
/// be added.
@Config(Unrestricted)
operation AddConstantFxP(constant : Double, fp : FixedPoint) : Unit is Adj + Ctl {
let n = Length(fp::Register);
use ys = Qubit[n];
Expand Down Expand Up @@ -46,6 +48,7 @@ operation AddConstantFxP(constant : Double, fp : FixedPoint) : Unit is Adj + Ctl
/// The current implementation requires the two fixed-point numbers
/// to have the same point position counting from the least-significant
/// bit, i.e., $n_i$ and $p_i$ must be equal.
@Config(Unrestricted)
operation AddFxP(fp1 : FixedPoint, fp2 : FixedPoint) : Unit is Adj + Ctl {
AssertPointPositionsIdenticalFxP([fp1, fp2]);

Expand All @@ -62,6 +65,7 @@ operation AddFxP(fp1 : FixedPoint, fp2 : FixedPoint) : Unit is Adj + Ctl {
/// # Remarks
/// Numerical inaccuracies may occur depending on the
/// bit-precision of the fixed-point number.
@Config(Unrestricted)
operation InvertFxP(fp : FixedPoint) : Unit is Adj + Ctl {
let (_, reg) = fp!;
Invert2sSI(reg);
Expand All @@ -79,6 +83,7 @@ operation InvertFxP(fp : FixedPoint) : Unit is Adj + Ctl {
/// # Remarks
/// Computes the difference by inverting `subtrahend` before and after adding
/// it to `minuend`. Notice that `minuend`, the first argument is updated.
@Config(Unrestricted)
operation SubtractFxP(minuend : FixedPoint, subtrahend : FixedPoint) : Unit is Adj + Ctl {
within {
InvertFxP(subtrahend);
Expand All @@ -102,13 +107,14 @@ operation SubtractFxP(minuend : FixedPoint, subtrahend : FixedPoint) : Unit is A
/// # Remarks
/// The current implementation requires the three fixed-point numbers
/// to have the same point position and the same number of qubits.
@Config(Unrestricted)
operation MultiplyFxP(fp1 : FixedPoint, fp2 : FixedPoint, result : FixedPoint) : Unit is Adj {

body (...) {
Controlled MultiplyFxP([], (fp1, fp2, result));
}
controlled (controls, ...) {
AssertFormatsAreIdenticalFxP([fp1, fp2, result]);
Facts.AssertFormatsAreIdenticalFxP([fp1, fp2, result]);
let n = Length(fp1::Register);

use tmpResult = Qubit[2 * n];
Expand All @@ -133,12 +139,13 @@ operation MultiplyFxP(fp1 : FixedPoint, fp2 : FixedPoint, result : FixedPoint) :
/// ## result
/// Result fixed-point number,
/// must be in state $\ket{0}$ initially.
@Config(Unrestricted)
operation SquareFxP(fp : FixedPoint, result : FixedPoint) : Unit is Adj {
body (...) {
Controlled SquareFxP([], (fp, result));
}
controlled (controls, ...) {
AssertFormatsAreIdenticalFxP([fp, result]);
Facts.AssertFormatsAreIdenticalFxP([fp, result]);
let n = Length(fp::Register);

use tmpResult = Qubit[2 * n];
Expand Down
19 changes: 14 additions & 5 deletions library/fixed_point/src/Polynomial.qs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import Facts.AssertFormatsAreIdenticalFxP, Facts.AssertAllZeroFxP;
import Types.FixedPoint;
import Init.PrepareFxP;
import Operations.MultiplyFxP, Operations.SquareFxP, Operations.AddConstantFxP;
import Facts.AssertFormatsAreIdenticalFxP;


/// # Summary
/// Evaluates a polynomial in a fixed-point representation.
Expand All @@ -19,12 +19,15 @@ import Operations.MultiplyFxP, Operations.SquareFxP, Operations.AddConstantFxP;
/// ## result
/// Output fixed-point number which will hold $P(x)$. Must be in state
/// $\ket{0}$ initially.
@Config(Unrestricted)
operation EvaluatePolynomialFxP(coefficients : Double[], fpx : FixedPoint, result : FixedPoint) : Unit is Adj {
body (...) {
Controlled EvaluatePolynomialFxP([], (coefficients, fpx, result));
}
controlled (controls, ...) {
AssertFormatsAreIdenticalFxP([fpx, result]);
import Operations.AddConstantFxP;

Facts.AssertFormatsAreIdenticalFxP([fpx, result]);
let degree = Length(coefficients) - 1;
let p = fpx::IntegerBits;
let n = Length(fpx::Register);
Expand All @@ -40,10 +43,11 @@ operation EvaluatePolynomialFxP(coefficients : Double[], fpx : FixedPoint, resul
let currentIterate = FixedPoint(p, qubits[(d - 1) * n..d * n - 1]);
let nextIterate = FixedPoint(p, qubits[(d - 2) * n..(d - 1) * n - 1]);
// multiply by x and then add current coefficient
MultiplyFxP(currentIterate, fpx, nextIterate);
Operations.MultiplyFxP(currentIterate, fpx, nextIterate);
AddConstantFxP(coefficients[d-1], nextIterate);
}
} apply {
import Operations.MultiplyFxP;
let finalIterate = FixedPoint(p, qubits[0..n-1]);
// final multiplication into the result register
Controlled MultiplyFxP(controls, (finalIterate, fpx, result));
Expand All @@ -67,12 +71,15 @@ operation EvaluatePolynomialFxP(coefficients : Double[], fpx : FixedPoint, resul
/// ## result
/// Output fixed-point number which will hold $P(x)$. Must be in state
/// $\ket{0}$ initially.
@Config(Unrestricted)
operation EvaluateEvenPolynomialFxP(coefficients : Double[], fpx : FixedPoint, result : FixedPoint) : Unit is Adj {
body (...) {
Controlled EvaluateEvenPolynomialFxP([], (coefficients, fpx, result));
}
controlled (controls, ...) {
AssertFormatsAreIdenticalFxP([fpx, result]);
import Operations.SquareFxP;

Facts.AssertFormatsAreIdenticalFxP([fpx, result]);
let halfDegree = Length(coefficients) - 1;
let n = Length(fpx::Register);

Expand Down Expand Up @@ -104,11 +111,13 @@ operation EvaluateEvenPolynomialFxP(coefficients : Double[], fpx : FixedPoint, r
/// ## result
/// Output fixed-point number which will hold P(x). Must be in state
/// $\ket{0}$ initially.
@Config(Unrestricted)
operation EvaluateOddPolynomialFxP(coefficients : Double[], fpx : FixedPoint, result : FixedPoint) : Unit is Adj {
body (...) {
Controlled EvaluateOddPolynomialFxP([], (coefficients, fpx, result));
}
controlled (controls, ...) {
import Operations.MultiplyFxP;
AssertFormatsAreIdenticalFxP([fpx, result]);
let halfDegree = Length(coefficients) - 1;
let n = Length(fpx::Register);
Expand Down
1 change: 1 addition & 0 deletions library/fixed_point/src/Reciprocal.qs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Std.Math.Min;
/// Fixed-point number to be inverted.
/// ## result
/// Fixed-point number that will hold the result. Must be initialized to $\ket{0.0}$.
@Config(Unrestricted)
operation ComputeReciprocalFxP(x : FixedPoint, result : FixedPoint) : Unit is Adj {
body (...) {
Controlled ComputeReciprocalFxP([], (x, result));
Expand Down
13 changes: 11 additions & 2 deletions library/fixed_point/src/Tests.qs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

import Init.PrepareFxP;
import Types.FixedPoint;
import Measurement.MeasureFxP;
import Std.Diagnostics.Fact;
import Std.Convert.IntAsDouble;
import Std.Math.AbsD;
import Operations.*;

@Config(Unrestricted)
@Test()
operation FxpMeasurementTest() : Unit {
for numQubits in 3..12 {
Expand All @@ -29,7 +29,9 @@ operation FxpMeasurementTest() : Unit {
}
}

@Config(Unrestricted)
operation TestConstantMeasurement(constant : Double, registerWidth : Int, integerWidth : Int, epsilon : Double) : Unit {
import Measurement.MeasureFxP;
use register = Qubit[registerWidth];
let newFxp = new FixedPoint { IntegerBits = integerWidth, Register = register };
PrepareFxP(constant, newFxp);
Expand All @@ -39,6 +41,7 @@ operation TestConstantMeasurement(constant : Double, registerWidth : Int, intege
ResetAll(register);
}

@Config(Unrestricted)
@Test()
operation FxpOperationTests() : Unit {
for i in 0..10 {
Expand All @@ -51,8 +54,9 @@ operation FxpOperationTests() : Unit {
TestSquare(constant1);
}
}

@Config(Unrestricted)
operation TestSquare(a : Double) : Unit {
import Measurement.MeasureFxP;
Message($"Testing Square({a})");
use resultRegister = Qubit[30];
let resultFxp = new FixedPoint { IntegerBits = 8, Register = resultRegister };
Expand All @@ -69,8 +73,10 @@ operation TestSquare(a : Double) : Unit {
ResetAll(aRegister);
}

@Config(Unrestricted)
// assume the second register that `op` takes is the result register
operation TestOperation(a : Double, b : Double, op : (FixedPoint, FixedPoint) => (), reference : (Double, Double) -> Double, name : String) : Unit {
import Measurement.MeasureFxP;
Message($"Testing {name}({a}, {b})");
use register1 = Qubit[20];
let aFxp = new FixedPoint { IntegerBits = 8, Register = register1 };
Expand All @@ -89,8 +95,11 @@ operation TestOperation(a : Double, b : Double, op : (FixedPoint, FixedPoint) =>
ResetAll(register1 + register2);
}

@Config(Unrestricted)
// assume the third register that `op` takes is the result register
operation TestOperation3(a : Double, b : Double, op : (FixedPoint, FixedPoint, FixedPoint) => (), reference : (Double, Double) -> Double, name : String) : Unit {
import Measurement.MeasureFxP;

Message($"Testing {name}({a}, {b})");
use register1 = Qubit[24];
let aFxp = new FixedPoint { IntegerBits = 8, Register = register1 };
Expand Down
Loading