Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into swernli/issue1154
Browse files Browse the repository at this point in the history
  • Loading branch information
swernli committed Jul 25, 2024
2 parents 81aee08 + 5763700 commit 9929c4a
Show file tree
Hide file tree
Showing 23 changed files with 289 additions and 105 deletions.
19 changes: 18 additions & 1 deletion compiler/qsc_eval/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ use crate::{
error::PackageSpan,
output::Receiver,
val::{self, Qubit, Value},
Error,
Error, Rc,
};
use num_bigint::BigInt;
use rand::{rngs::StdRng, Rng};
use rustc_hash::FxHashSet;
use std::array;
use std::convert::TryFrom;

#[allow(clippy::too_many_lines)]
pub(crate) fn call(
Expand All @@ -36,6 +37,22 @@ pub(crate) fn call(
#[allow(clippy::cast_precision_loss)]
"IntAsDouble" => Ok(Value::Double(arg.unwrap_int() as f64)),
"IntAsBigInt" => Ok(Value::BigInt(BigInt::from(arg.unwrap_int()))),
"DoubleAsStringWithPrecision" => {
let [input, prec_val] = unwrap_tuple(arg);
let prec_int = prec_val.unwrap_int();
if prec_int < 0 {
Err(Error::InvalidNegativeInt(prec_int, arg_span))
} else {
let precision = usize::try_from(prec_int).expect("integer value");
let is_zero = if precision == 0 { "." } else { "" };
Ok(Value::String(Rc::from(format!(
"{:.*}{}",
precision,
input.unwrap_double(),
is_zero
))))
}
}
"DumpMachine" => {
let (state, qubit_count) = sim.capture_quantum_state();
match out.state(state, qubit_count) {
Expand Down
45 changes: 45 additions & 0 deletions compiler/qsc_eval/src/intrinsic/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,51 @@ fn int_as_double_precision_loss() {
);
}

#[test]
fn double_as_string_with_precision() {
check_intrinsic_result(
"",
"Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.8414709848078965, 4)",
&expect!["0.8415"],
);
}

#[test]
fn double_as_string_with_precision_extend() {
check_intrinsic_result(
"",
"Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.8, 5)",
&expect!["0.80000"],
);
}

#[test]
fn double_as_string_with_precision_negative_error() {
check_intrinsic_result(
"",
"Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.8, -5)",
&expect!["negative integers cannot be used here: -5"],
);
}

#[test]
fn double_as_string_with_zero_precision() {
check_intrinsic_result(
"",
"Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.47, 0)",
&expect!["0."],
);
}

#[test]
fn double_as_string_with_zero_precision_rounding() {
check_intrinsic_result(
"",
"Microsoft.Quantum.Convert.DoubleAsStringWithPrecision(0.913, 0)",
&expect!["1."],
);
}

#[test]
fn dump_machine() {
check_intrinsic_output(
Expand Down
4 changes: 2 additions & 2 deletions compiler/qsc_eval/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3726,7 +3726,7 @@ fn controlled_operation_with_duplicate_controls_fails() {
1,
),
item: LocalItemId(
127,
128,
),
},
caller: PackageId(
Expand Down Expand Up @@ -3776,7 +3776,7 @@ fn controlled_operation_with_target_in_controls_fails() {
1,
),
item: LocalItemId(
127,
128,
),
},
caller: PackageId(
Expand Down
34 changes: 30 additions & 4 deletions compiler/qsc_frontend/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ pub enum Res {
ExportedItem(ItemId, Option<Ident>),
}

impl Res {
#[must_use]
pub fn item_id(&self) -> Option<ItemId> {
match self {
Res::Item(id, _) | Res::ExportedItem(id, _) => Some(*id),
_ => None,
}
}
}

#[derive(Clone, Debug, Diagnostic, Error, PartialEq)]
pub(super) enum Error {
#[error("`{name}` could refer to the item in `{first_open}` or `{second_open}`")]
Expand Down Expand Up @@ -923,10 +933,26 @@ impl Resolver {
(false, Some(entry), _) | (true, _, Some(entry))
if matches!(entry.source, ItemSource::Imported(..)) =>
{
let err =
Error::ImportedDuplicate(local_name.to_string(), decl_item.name().span);
self.errors.push(err);
continue;
// only push this error if the import is of a different item.
// this is for the re-runnability of jupyter cells.
// we want to be able to re-run a cell which may have an import in
// it, meaning it would evaluate the same import multiple times.
//
// if the import is of a different item, though, then we should throw an
// error because the import introduces a conflict.
match (term_result, ty_result) {
(Ok(res), _) | (_, Ok(res)) if res.item_id() == Some(entry.id) => {
continue;
}
_ => {
let err = Error::ImportedDuplicate(
local_name.to_string(),
decl_item.name().span,
);
self.errors.push(err);
continue;
}
}
}
// special case:
// if this is an export of an import with an alias,
Expand Down
32 changes: 29 additions & 3 deletions compiler/qsc_frontend/src/resolve/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4472,6 +4472,7 @@ fn import_self() {
);
}

// this should be allowed for jupyter cell re-runnability
#[test]
fn import_duplicate_symbol() {
check(
Expand All @@ -4490,12 +4491,11 @@ fn import_duplicate_symbol() {
namespace namespace9 {
operation item2() : Unit {}
}
// ImportedDuplicate("Baz", Span { lo: 49, hi: 52 })
"#]],
);
}

// this should be allowed for jupyter cell re-runnability
#[test]
fn import_duplicate_symbol_different_name() {
check(
Expand All @@ -4516,11 +4516,37 @@ fn import_duplicate_symbol_different_name() {
namespace namespace9 {
operation item2() : Unit {}
}
"#]],
);
}

// this should be allowed for jupyter cell re-runnability
#[test]
fn disallow_importing_different_items_with_same_name() {
check(
indoc! { r#"
namespace Main {
import Foo.Bar.Baz, Foo.Bar.Baz2 as Baz;
}
namespace Foo.Bar {
operation Baz() : Unit {}
operation Baz2() : Unit {}
}
"# },
&expect![[r#"
namespace namespace7 {
import item2, item3;
}
namespace namespace9 {
operation item2() : Unit {}
operation item3() : Unit {}
}
// ImportedDuplicate("Baz", Span { lo: 65, hi: 68 })
// ImportedDuplicate("Baz", Span { lo: 57, hi: 60 })
"#]],
);
}

#[test]
fn import_takes_precedence_over_local_decl() {
check(
Expand Down
2 changes: 1 addition & 1 deletion library/qs_source/src/std/canon.qs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ namespace Microsoft.Quantum.Canon {
/// ```
operation ApplyPauliFromBitString(pauli : Pauli, bitApply : Bool, bits : Bool[], qubits : Qubit[]) : Unit is Adj + Ctl {
let nBits = Length(bits);
Fact(nBits == Length(qubits), "Number of control bits must be equal to number of control qubits.");
Fact(nBits == Length(qubits), "Number of bits must be equal to number of qubits.");
for i in 0..nBits - 1 {
if bits[i] == bitApply {
ApplyP(pauli, qubits[i]);
Expand Down
22 changes: 21 additions & 1 deletion library/qs_source/src/std/convert.qs
Original file line number Diff line number Diff line change
Expand Up @@ -264,5 +264,25 @@ namespace Microsoft.Quantum.Convert {
);
}

export IntAsDouble, IntAsBigInt, ResultAsBool, BoolAsResult, BoolArrayAsInt, IntAsBoolArray, BoolArrayAsBigInt, BigIntAsBoolArray, ResultArrayAsInt, ResultArrayAsBoolArray, BoolArrayAsResultArray, ComplexAsComplexPolar, ComplexPolarAsComplex;
/// # Summary
/// Converts a given double-precision floating-point number to a string representation with desired precision, rounding if required.
///
/// # Input
/// ## input
/// Double to be converted.
/// ## precision
/// Non-negative number of digits after the decimal point.
///
/// # Example
/// ```qsharp
/// Message($"{DoubleAsStringWithPrecision(0.354, 2)}"); // Prints 0.35
/// Message($"{DoubleAsStringWithPrecision(0.485, 1)}"); // Prints 0.5
/// Message($"{DoubleAsStringWithPrecision(5.6, 4)}"); // Prints 5.6000
/// Message($"{DoubleAsStringWithPrecision(2.268, 0)}"); // Prints 2
/// ```
function DoubleAsStringWithPrecision(input : Double, precision : Int) : String {
body intrinsic;
}

export IntAsDouble, IntAsBigInt, ResultAsBool, BoolAsResult, BoolArrayAsInt, IntAsBoolArray, BoolArrayAsBigInt, BigIntAsBoolArray, ResultArrayAsInt, ResultArrayAsBoolArray, BoolArrayAsResultArray, ComplexAsComplexPolar, ComplexPolarAsComplex, DoubleAsStringWithPrecision;
}
2 changes: 0 additions & 2 deletions library/qs_source/src/std/internal.qs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,4 @@ namespace Microsoft.Quantum.Intrinsic {

targets
}

export CH, CCH, ApplyGlobalPhase, ControllableGlobalPhase, GlobalPhase, CRz, CS, CT, MapPauli, EntangleForJointMeasure, CollectControls, AdjustForSingleControl, AND, PhaseCCX, CCZ, CCY, CRxx, CRyy, CRzz, IndicesOfNonIdentity, RemovePauliI, SpreadZ;
}
2 changes: 1 addition & 1 deletion library/qs_source/src/std/math.qs
Original file line number Diff line number Diff line change
Expand Up @@ -1454,5 +1454,5 @@ namespace Microsoft.Quantum.Math {
2.0^IntAsDouble(integerBits - 1) - 2.0^(-IntAsDouble(fractionalBits))
}

export PI, E, LogOf2, IsNaN, IsInfinite, SignI, SignD, SignL, AbsI, AbsD, AbsL, MaxI, MaxD, MaxL, MinI, MinD, MinL, Max, Min, ArcCos, ArcSin, ArcTan, ArcTan2, Cos, Cosh, Sin, Sinh, Tan, Tanh, ArcCosh, ArcSinh, ArcTanh, Sqrt, Log, Log10, Lg, Truncate, ExtendedTruncation, Ceiling, Floor, Round, DivRemI, DivRemL, ModulusI, ModulusL, ExpModI, ExpModL, InverseModI, InverseModL, GreatestCommonDivisorI, GreatestCommonDivisorL, ExtendedGreatestCommonDivisorI, ExtendedGreatestCommonDivisorL, IsCoprimeI, IsCoprimeL, ContinuedFractionConvergentI, ContinuedFractionConvergentL, RealMod, BitSizeI, BitSizeL, TrailingZeroCountI, TrailingZeroCountL, HammingWeightI, FactorialI, FactorialL, ApproximateFactorial, LogGammaD, LogFactorialD, Binom, SquaredNorm, PNorm, PNormalized, Complex, ComplexPolar, AbsSquaredComplex, AbsComplex, ArgComplex, AbsSquaredComplexPolar, AbsComplexPolar, ArgComplexPolar, NegationC, NegationCP, PlusC, PlusCP, MinusC, MinusCP, TimesC, TimesCP, PowCAsCP, PowC, PowCP, DividedByC, DividedByCP, SmallestFixedPoint, LargestFixedPoint;
export PI, E, LogOf2, IsNaN, IsInfinite, SignI, SignD, SignL, AbsI, AbsD, AbsL, MaxI, MaxD, MaxL, MinI, MinD, MinL, Max, Min, ArcCos, ArcSin, ArcTan, ArcTan2, Cos, Cosh, Sin, Sinh, Tan, Tanh, ArcCosh, ArcSinh, ArcTanh, Sqrt, Log, Log10, Lg, Truncate, Ceiling, Floor, Round, DivRemI, DivRemL, ModulusI, ModulusL, ExpModI, ExpModL, InverseModI, InverseModL, GreatestCommonDivisorI, GreatestCommonDivisorL, ExtendedGreatestCommonDivisorI, ExtendedGreatestCommonDivisorL, IsCoprimeI, IsCoprimeL, ContinuedFractionConvergentI, ContinuedFractionConvergentL, RealMod, BitSizeI, BitSizeL, TrailingZeroCountI, TrailingZeroCountL, HammingWeightI, FactorialI, FactorialL, ApproximateFactorial, LogGammaD, LogFactorialD, Binom, SquaredNorm, PNorm, PNormalized, Complex, ComplexPolar, AbsSquaredComplex, AbsComplex, ArgComplex, AbsSquaredComplexPolar, AbsComplexPolar, ArgComplexPolar, NegationC, NegationCP, PlusC, PlusCP, MinusC, MinusCP, TimesC, TimesCP, PowC, PowCP, DividedByC, DividedByCP, SmallestFixedPoint, LargestFixedPoint;
}
1 change: 0 additions & 1 deletion library/qs_source/src/std/unstable_arithmetic_internal.qs
Original file line number Diff line number Diff line change
Expand Up @@ -582,5 +582,4 @@ namespace Microsoft.Quantum.Unstable.Arithmetic {
ApplyAndAssuming0Target(Tail(tgtsLeft), Tail(tgtsRight), Tail(tgts));
}
}
export ApplyActionIfGreaterThanOrEqualConstant, ApplyActionIfSumOverflows, ApplyAsSinglyControlled, PhaseGradient;
}
2 changes: 1 addition & 1 deletion library/qs_source/src/std/unstable_table_lookup.qs
Original file line number Diff line number Diff line change
Expand Up @@ -274,5 +274,5 @@ namespace Microsoft.Quantum.Unstable.TableLookup {
}
}

export Select, WriteMemoryContents, Unlookup, MustBeFixed, EncodeUnary;
export Select;
}
3 changes: 1 addition & 2 deletions noisy_simulator/benches/noisy_simulator.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use std::time::Duration;

use criterion::{criterion_group, criterion_main, Criterion};
use nalgebra::dmatrix;
use noisy_simulator::{
DensityMatrixSimulator, Error, NoisySimulator, Operation, StateVectorSimulator,
};
use std::time::Duration;

fn ten_qubits_ten_operations<NS: NoisySimulator>() -> Result<(), Error> {
let x_gate = Operation::new(vec![
Expand Down
4 changes: 1 addition & 3 deletions noisy_simulator/src/density_matrix_simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,7 @@ impl DensityMatrix {
}
self.trace_change *= trace;
let renormalization_factor = 1.0 / trace;
for entry in self.data.iter_mut() {
*entry *= renormalization_factor;
}
self.data.scale_mut(renormalization_factor);
Ok(())
}

Expand Down
Loading

0 comments on commit 9929c4a

Please sign in to comment.