diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..a2fb9f977b6 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# Automatically tag in libraries maintainers on Q# API changes. +*.qs @microsoft/quantumlibraries diff --git a/.github/workflows/automerge.yml b/.github/workflows/automerge.yml new file mode 100644 index 00000000000..d45a296b737 --- /dev/null +++ b/.github/workflows/automerge.yml @@ -0,0 +1,38 @@ +# This action allows using the automerge label to automatically merge in pull requests that have been reviewed and that pass +# status checks (similar to the autocomplete functionality of Azure DevOps). +name: automerge +on: + pull_request: + # Note that we only support automerge on branches that have required checks. + branches: + - master + - feature/* + types: + - labeled + - unlabeled + - synchronize + - opened + - edited + - ready_for_review + - reopened + - unlocked + pull_request_review: + # Note that we only support automerge on branches that have required checks. + branches: + - master + - feature/* + types: + - submitted + check_suite: + types: + - completed + status: {} +jobs: + automerge: + runs-on: ubuntu-latest + steps: + - name: automerge + uses: "pascalgn/automerge-action@4536e8847eb62fe2f0ee52c8fa92d17aa97f932f" + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + MERGE_METHOD: squash diff --git a/Simulation.sln b/Simulation.sln index a6bc9fd6d03..685cb9857a7 100644 --- a/Simulation.sln +++ b/Simulation.sln @@ -61,6 +61,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Simulation", "Simulation", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Quantum.QSharp.Foundation", "src\Simulation\QsharpFoundation\Microsoft.Quantum.QSharp.Foundation.csproj", "{50614DF8-2DD8-4A0B-9AA9-7843BA563572}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Simulators.Tests", "Simulators.Tests", "{0E9E6621-B3B9-42F9-AA13-AF97ADA026E9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestProjects", "TestProjects", "{3CB6D1AC-C606-433D-8D83-182B4A0475F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Library with Spaces", "src\Simulation\Simulators.Tests\TestProjects\Library with Spaces\Library with Spaces.csproj", "{F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -409,6 +415,22 @@ Global {50614DF8-2DD8-4A0B-9AA9-7843BA563572}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU {50614DF8-2DD8-4A0B-9AA9-7843BA563572}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU {50614DF8-2DD8-4A0B-9AA9-7843BA563572}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.Debug|x64.ActiveCfg = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.Debug|x64.Build.0 = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.Release|Any CPU.Build.0 = Release|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.Release|x64.ActiveCfg = Release|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.Release|x64.Build.0 = Release|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.RelWithDebInfo|Any CPU.ActiveCfg = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.RelWithDebInfo|Any CPU.Build.0 = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.RelWithDebInfo|x64.ActiveCfg = Debug|Any CPU + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5}.RelWithDebInfo|x64.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -437,6 +459,9 @@ Global {4858E5E3-23FA-4928-B99A-54065875A2B9} = {37CDC768-16D4-4574-8553-07D99D0A72F7} {83C5FC86-9D37-4679-9D91-66288DD975AE} = {2195B643-E782-42E0-9FB0-26F6D90131E6} {50614DF8-2DD8-4A0B-9AA9-7843BA563572} = {83C5FC86-9D37-4679-9D91-66288DD975AE} + {0E9E6621-B3B9-42F9-AA13-AF97ADA026E9} = {83C5FC86-9D37-4679-9D91-66288DD975AE} + {3CB6D1AC-C606-433D-8D83-182B4A0475F1} = {0E9E6621-B3B9-42F9-AA13-AF97ADA026E9} + {F366DB0F-EF25-4196-94F1-0FCC9B9DB1B5} = {3CB6D1AC-C606-433D-8D83-182B4A0475F1} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {929C0464-86D8-4F70-8835-0A5EAF930821} diff --git a/src/Azure/Azure.Quantum.Client/Storage/StorageHelper.cs b/src/Azure/Azure.Quantum.Client/Storage/StorageHelper.cs index e3ee0787da2..2d4f80b713c 100644 --- a/src/Azure/Azure.Quantum.Client/Storage/StorageHelper.cs +++ b/src/Azure/Azure.Quantum.Client/Storage/StorageHelper.cs @@ -62,7 +62,7 @@ public async Task UploadBlobAsync( try { // Ensure container is created - await containerClient.CreateIfNotExistsAsync(PublicAccessType.Blob, cancellationToken: cancellationToken); + await containerClient.CreateIfNotExistsAsync(PublicAccessType.None, cancellationToken: cancellationToken); // Upload blob BlobClient blob = containerClient.GetBlobClient(blobName); diff --git a/src/Simulation/Common/IQuantumProcessor.cs b/src/Simulation/Common/IQuantumProcessor.cs index 4152249b139..dd61aed3bdd 100644 --- a/src/Simulation/Common/IQuantumProcessor.cs +++ b/src/Simulation/Common/IQuantumProcessor.cs @@ -517,7 +517,7 @@ public interface IQuantumProcessor void Assert(IQArray bases, IQArray qubits, Result result, string msg); /// - /// Called when Microsoft.Quantum.Intrinsic.Assert is called in Q#. + /// Called when Microsoft.Quantum.Intrinsic.AssertProb is called in Q#. /// /// /// The names and the order of the parameters is similar to the corresponding Q# operation./ diff --git a/src/Simulation/Common/SimulatorBase.cs b/src/Simulation/Common/SimulatorBase.cs index 1440e2112db..41f566ea641 100644 --- a/src/Simulation/Common/SimulatorBase.cs +++ b/src/Simulation/Common/SimulatorBase.cs @@ -31,6 +31,14 @@ public abstract class SimulatorBase : AbstractFactory, IOperat public event Action? OnLog = null; public event Action>? OnException = null; + + /// + /// An event fired whenever a simulator has additional diagnostic data + /// available for display (e.g. state information, assertion details, + /// execution traces). + /// + public event Action? OnDisplayableDiagnostic = null; + public IQubitManager? QubitManager { get; } public abstract string Name { get; } @@ -182,6 +190,17 @@ public void EnableExceptionPrinting() OnException += WriteStackTraceToLog; } + /// + /// Sends diagnostic data to any listening display handlers. + /// Display handlers may discard any unrecognized data, such that + /// no guarantee is made as to any particular action taken as a result + /// of calling this method. + /// + protected void MaybeDisplayDiagnostic(object data) + { + OnDisplayableDiagnostic?.Invoke(data); + } + /// /// Disables default handling of stack traces, such that stack diff --git a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs index 31fb2e62e04..90416d37e9e 100644 --- a/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs +++ b/src/Simulation/CsharpGeneration.Tests/SimulationCodeTests.fs @@ -7,6 +7,7 @@ open System open System.Collections.Immutable open System.IO open System.Globalization +open System.Web open Microsoft.CodeAnalysis open Microsoft.CodeAnalysis.CSharp @@ -218,9 +219,13 @@ namespace N1 let testOneFile fileName (expected:string) = - let expected = expected.Replace("%%%", (Uri(Path.GetFullPath fileName)).AbsolutePath) - let expected = expected.Replace("%%", (Path.GetFullPath fileName).Replace("\\", "\\\\")) - let tree = parse [(Path.Combine("Circuits","Intrinsic.qs")); fileName] + let fullPath = Path.GetFullPath fileName + let escapeCSharpString (s : string) = SymbolDisplay.FormatLiteral (s, false) + let expected = + expected + |> (fun s -> s.Replace("%%%", fullPath |> HttpUtility.JavaScriptStringEncode |> escapeCSharpString)) + |> (fun s -> s.Replace("%%", fullPath |> escapeCSharpString)) + let tree = parse [Path.Combine ("Circuits", "Intrinsic.qs"); fileName] let actual = CodegenContext.Create (tree, ImmutableDictionary.Empty) |> generate (Path.GetFullPath fileName |> NonNullable.New) @@ -2307,7 +2312,7 @@ namespace N1 false |> testOne randomOperation let testOneClass (_,op : QsCallable) executionTarget (expected : string) = - let expected = expected.Replace("%%%", op.SourceFile.Value) + let expected = expected.Replace("%%%", HttpUtility.JavaScriptStringEncode op.SourceFile.Value) let assemblyConstants = new System.Collections.Generic.KeyValuePair<_,_> (AssemblyConstants.ExecutionTarget, executionTarget) |> Seq.singleton @@ -3397,7 +3402,7 @@ using Microsoft.Quantum.Simulation.Core; #line hidden namespace Microsoft.Quantum.Tests.Inline { - [SourceLocation("%%%", OperationFunctor.Body, 7, -1)] + [SourceLocation("%%", OperationFunctor.Body, 7, -1)] public partial class HelloWorld : Operation, ICallable { public HelloWorld(IOperationFactory m) : base(m) @@ -3454,7 +3459,7 @@ using Microsoft.Quantum.Simulation.Core; #line hidden namespace Microsoft.Quantum.Tests.LineNumbers { - [SourceLocation("%%%", OperationFunctor.Body, 9, -1)] + [SourceLocation("%%", OperationFunctor.Body, 9, -1)] public partial class TestLineInBlocks : Operation, ICallable { public TestLineInBlocks(IOperationFactory m) : base(m) @@ -3628,7 +3633,7 @@ namespace Microsoft.Quantum.Diagnostics #line hidden namespace Microsoft.Quantum.Tests.UnitTests { - [SourceLocation("%%%", OperationFunctor.Body, 22, 26)] + [SourceLocation("%%", OperationFunctor.Body, 22, 26)] public partial class UnitTest1 : Operation, ICallable { public UnitTest1(IOperationFactory m) : base(m) @@ -3651,7 +3656,7 @@ namespace Microsoft.Quantum.Tests.UnitTests [Xunit.Trait("Target", "QuantumSimulator")] [Xunit.Trait("Name", "UnitTest1")] public void UnitTest1() -#line 22 "%%%" +#line 22 "%%" { var sim = new Microsoft.Quantum.Simulation.Simulators.QuantumSimulator(); if (sim is Microsoft.Quantum.Simulation.Common.SimulatorBase baseSim && this.Output != null) @@ -3683,7 +3688,7 @@ namespace Microsoft.Quantum.Tests.UnitTests [Xunit.Trait("Target", "ToffoliSimulator")] [Xunit.Trait("Name", "UnitTest1")] public void UnitTest1() -#line 22 "%%%" +#line 22 "%%" { var sim = new Microsoft.Quantum.Simulation.Simulators.ToffoliSimulator(); if (sim is Microsoft.Quantum.Simulation.Common.SimulatorBase baseSim && this.Output != null) @@ -3721,7 +3726,7 @@ namespace Microsoft.Quantum.Tests.UnitTests } } - [SourceLocation("%%%", OperationFunctor.Body, 26, -1)] + [SourceLocation("%%", OperationFunctor.Body, 26, -1)] public partial class UnitTest2 : Operation, ICallable { public UnitTest2(IOperationFactory m) : base(m) @@ -3744,7 +3749,7 @@ namespace Microsoft.Quantum.Tests.UnitTests [Xunit.Trait("Target", "CustomSimulator")] [Xunit.Trait("Name", "UnitTest2")] public void UnitTest2() -#line 26 "%%%" +#line 26 "%%" { var sim = new SomeNamespace.CustomSimulator(); if (sim is Microsoft.Quantum.Simulation.Common.SimulatorBase baseSim && this.Output != null) diff --git a/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj b/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj index 1bc1a267e83..59d46b17145 100644 --- a/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj +++ b/src/Simulation/CsharpGeneration/Microsoft.Quantum.CsharpGeneration.fsproj @@ -21,7 +21,7 @@ - + diff --git a/src/Simulation/CsharpGeneration/SimulationCode.fs b/src/Simulation/CsharpGeneration/SimulationCode.fs index e0c6b0c0810..30e83926c90 100644 --- a/src/Simulation/CsharpGeneration/SimulationCode.fs +++ b/src/Simulation/CsharpGeneration/SimulationCode.fs @@ -1573,13 +1573,10 @@ module SimulationCode = generator.Apply elements // Returns only those namespaces and their elements that are defined for the given file. - let findLocalElements selector fileName syntaxTree = - let path = - match CompilationBuilder.CompilationUnitManager.TryGetUri fileName with - | true, uri -> uri.AbsolutePath |> NonNullable.New - | false, _ -> NonNullable.New "" + let findLocalElements selector (fileName : NonNullable) syntaxTree = syntaxTree - |> Seq.map (fun ns -> (ns.Name, (FilterBySourceFile.Apply (ns, path)).Elements |> Seq.choose selector |> Seq.toList)) + |> Seq.map (fun ns -> + (ns.Name, (FilterBySourceFile.Apply (ns, fileName)).Elements |> Seq.choose selector |> Seq.toList)) |> Seq.sortBy fst |> Seq.filter (fun (_,elements) -> not elements.IsEmpty) |> Seq.toList diff --git a/src/Simulation/EntryPointDriver.Tests/Tests.Microsoft.Quantum.EntryPointDriver.fsproj b/src/Simulation/EntryPointDriver.Tests/Tests.Microsoft.Quantum.EntryPointDriver.fsproj index 8ab17e90bed..937028048ea 100644 --- a/src/Simulation/EntryPointDriver.Tests/Tests.Microsoft.Quantum.EntryPointDriver.fsproj +++ b/src/Simulation/EntryPointDriver.Tests/Tests.Microsoft.Quantum.EntryPointDriver.fsproj @@ -5,6 +5,7 @@ false false Microsoft.Quantum.EntryPointDriver.Tests + x64 diff --git a/src/Simulation/EntryPointDriver.Tests/Tests.fs b/src/Simulation/EntryPointDriver.Tests/Tests.fs index 369381aa86a..fda063f478f 100644 --- a/src/Simulation/EntryPointDriver.Tests/Tests.fs +++ b/src/Simulation/EntryPointDriver.Tests/Tests.fs @@ -475,15 +475,15 @@ let ``Shadows --shots`` () = // The expected output from the resources estimator. let private resourceSummary = - "Metric Sum - CNOT 0 - QubitClifford 1 - R 0 - Measure 1 - T 0 - Depth 0 - Width 1 - BorrowedWidth 0" + "Metric Sum Max + CNOT 0 0 + QubitClifford 1 1 + R 0 0 + Measure 1 1 + T 0 0 + Depth 0 0 + Width 1 1 + BorrowedWidth 0 0" [] let ``Supports QuantumSimulator`` () = diff --git a/src/Simulation/EntryPointDriver/Microsoft.Quantum.EntryPointDriver.csproj b/src/Simulation/EntryPointDriver/Microsoft.Quantum.EntryPointDriver.csproj index ee9dd9b1dd8..2fa2201551c 100644 --- a/src/Simulation/EntryPointDriver/Microsoft.Quantum.EntryPointDriver.csproj +++ b/src/Simulation/EntryPointDriver/Microsoft.Quantum.EntryPointDriver.csproj @@ -7,6 +7,18 @@ enable Microsoft.Quantum.EntryPointDriver The standard command-line interface for standalone Q# console applications. + x64 + + + + Microsoft + Entry point driver for Q# command line applications. + See: https://docs.microsoft.com/en-us/quantum/relnotes/ + MIT + https://github.com/microsoft/qsharp-runtime + https://secure.gravatar.com/avatar/bd1f02955b2853ba0a3b1cdc2434e8ec.png + Quantum Q# Qsharp + true diff --git a/src/Simulation/QCTraceSimulator.Tests/Circuits/RandomTests.qs b/src/Simulation/QCTraceSimulator.Tests/Circuits/RandomTests.qs new file mode 100644 index 00000000000..b37c8c0c33f --- /dev/null +++ b/src/Simulation/QCTraceSimulator.Tests/Circuits/RandomTests.qs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + + +namespace Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.Tests { + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; + + internal function Fact(condition : Bool, message : String) : Unit { + if (not condition) { + fail message; + } + } + + @Test("ResourcesEstimator") + /// # Summary + /// Checks for regression against microsoft/qsharp-runtime#256. + operation CheckRandomInCorrectRange() : Unit { + for (idxTrial in 0..99) { + let sample = Random([1.0, 2.0, 2.0]); + + Fact(0 <= sample and sample <= 2, $"sample was {sample}, not in range [0, 2]"); + } + } +} diff --git a/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj b/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj index 93d81f193bb..4bbaca22c96 100644 --- a/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj +++ b/src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/QsharpCore/Arrays/Enumeration.qs b/src/Simulation/QsharpCore/Arrays/Enumeration.qs new file mode 100644 index 00000000000..a90383b1ab5 --- /dev/null +++ b/src/Simulation/QsharpCore/Arrays/Enumeration.qs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Arrays { + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Canon; + + /// # Summary + /// Given an array, returns a range over the indices of that array, suitable + /// for use in a for loop. + /// + /// # Type Parameters + /// ## 'TElement + /// The type of elements of the array. + /// + /// # Input + /// ## array + /// An array for which a range of indices should be returned. + /// + /// # Output + /// A range over all indices of the array. + /// + /// # Example + /// The following `for` loops are equivalent: + /// ```Q# + /// for (idx in IndexRange(array)) { ... } + /// for (idx in IndexRange(array)) { ... } + /// ``` + function IndexRange<'TElement>(array : 'TElement[]) : Range { + return 0..(Length(array) - 1); + } + +} diff --git a/src/Simulation/QsharpCore/Canon/NoOp.qs b/src/Simulation/QsharpCore/Canon/NoOp.qs new file mode 100644 index 00000000000..b9a778f6e26 --- /dev/null +++ b/src/Simulation/QsharpCore/Canon/NoOp.qs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Canon { + + /// # Summary + /// Performs the identity operation (no-op) on an argument. + /// + /// # Description + /// This operation takes a value of any type and does nothing to it. + /// This can be useful whenever an input of an operation type is expected, + /// but no action should be taken. + /// For instance, if a particular error correction syndrome indicates that + /// no error has occurred, `NoOp` may be the correct recovery + /// procedure. + /// Similarly, if an operation expects a state preparation procedure as + /// input, `NoOp` can be used to prepare the state + /// $\ket{0 \cdots 0}$. + /// + /// # Input + /// ## input + /// A value to be ignored. + /// + /// # Remarks + /// In almost all cases, the type parameter for `NoOp` needs to be specified + /// explicitly. For instance, `NoOp` is identical to + /// . + /// + /// # See Also + /// - Microsoft.Quantum.Intrinsic.I + operation NoOp<'T>(input : 'T) : Unit is Adj + Ctl { + } + + + /// # Summary + /// Ignores the output of an operation or function. + /// + /// # Input + /// ## value + /// A value to be ignored. + function Ignore<'T> (value : 'T) : Unit { + return (); + } + +} diff --git a/src/Simulation/QsharpCore/Intrinsic.qs b/src/Simulation/QsharpCore/Intrinsic.qs index 5ed04498990..b546a5e7d1f 100644 --- a/src/Simulation/QsharpCore/Intrinsic.qs +++ b/src/Simulation/QsharpCore/Intrinsic.qs @@ -107,8 +107,10 @@ namespace Microsoft.Quantum.Intrinsic { /// # Summary - /// Applies the π/4 phase gate to a single qubit. + /// Applies the S gate to a single qubit. /// + /// # Description + /// This operation can be simulated by the unitary matrix /// \begin{align} /// S \mathrel{:=} /// \begin{bmatrix} @@ -120,15 +122,17 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubit /// Qubit to which the gate should be applied. - operation S (qubit : Qubit) : Unit + operation S(qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; } /// # Summary - /// Applies the π/8 gate to a single qubit. + /// Applies the T gate to a single qubit. /// + /// # Description + /// This operation can be simulated by the unitary matrix /// \begin{align} /// T \mathrel{:=} /// \begin{bmatrix} @@ -140,7 +144,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Input /// ## qubit /// Qubit to which the gate should be applied. - operation T (qubit : Qubit) : Unit + operation T(qubit : Qubit) : Unit is Adj + Ctl { body intrinsic; } @@ -175,8 +179,7 @@ namespace Microsoft.Quantum.Intrinsic { operation CNOT (control : Qubit, target : Qubit) : Unit is Adj + Ctl { - body (...) - { + body (...) { Controlled X([control], target); } @@ -202,8 +205,7 @@ namespace Microsoft.Quantum.Intrinsic { /// ``` operation CCNOT (control1 : Qubit, control2 : Qubit, target : Qubit) : Unit is Adj + Ctl { - body (...) - { + body (...) { Controlled X([control1, control2], target); } diff --git a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj index c2a13801b54..aff69318801 100644 --- a/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj +++ b/src/Simulation/QsharpCore/Microsoft.Quantum.QSharp.Core.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/QsharpCore/Primitive.qs b/src/Simulation/QsharpCore/Primitive.qs deleted file mode 100644 index 85fb806872d..00000000000 --- a/src/Simulation/QsharpCore/Primitive.qs +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -namespace Microsoft.Quantum.Primitive { - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.random". - @Deprecated("Microsoft.Quantum.Intrinsic.Random") - operation Random (probs : Double[]) : Int { - return Microsoft.Quantum.Intrinsic.Random(probs); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.assert". - @Deprecated("Microsoft.Quantum.Intrinsic.Assert") - operation Assert (bases : Pauli[], qubits : Qubit[], result : Result, msg : String) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.Assert(bases, qubits, result, msg); - } - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.assertprob". - @Deprecated("Microsoft.Quantum.Intrinsic.AssertProb") - operation AssertProb (bases : Pauli[], qubits : Qubit[], result : Result, prob : Double, msg : String, tol : Double) : Unit - { - body (...) { - Microsoft.Quantum.Intrinsic.AssertProb(bases, qubits, result, prob, msg, tol); - } - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.message". - @Deprecated("Microsoft.Quantum.Intrinsic.Message") - function Message (msg : String) : Unit { - return Microsoft.Quantum.Intrinsic.Message(msg); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.i". - @Deprecated("Microsoft.Quantum.Intrinsic.I") - operation I (qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.I(qubit); - } - adjoint self; - controlled auto; - controlled adjoint self; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.x". - @Deprecated("Microsoft.Quantum.Intrinsic.X") - operation X (qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.X(qubit); - } - adjoint self; - controlled auto; - controlled adjoint self; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.y". - @Deprecated("Microsoft.Quantum.Intrinsic.Y") - operation Y (qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.Y(qubit); - } - adjoint self; - controlled auto; - controlled adjoint self; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.z". - @Deprecated("Microsoft.Quantum.Intrinsic.Z") - operation Z (qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.Z(qubit); - } - adjoint self; - controlled auto; - controlled adjoint self; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.h". - @Deprecated("Microsoft.Quantum.Intrinsic.H") - operation H (qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.H(qubit); - } - adjoint self; - controlled auto; - controlled adjoint self; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.s". - @Deprecated("Microsoft.Quantum.Intrinsic.S") - operation S (qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.S(qubit); - } - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.t". - @Deprecated("Microsoft.Quantum.Intrinsic.T") - operation T (qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.T(qubit); - } - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.cnot". - @Deprecated("Microsoft.Quantum.Intrinsic.CNOT") - operation CNOT (control : Qubit, target : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.CNOT(control, target); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.ccnot". - @Deprecated("Microsoft.Quantum.Intrinsic.CCNOT") - operation CCNOT (control1 : Qubit, control2 : Qubit, target : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.CCNOT(control1, control2, target); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.swap". - @Deprecated("Microsoft.Quantum.Intrinsic.SWAP") - operation SWAP (qubit1 : Qubit, qubit2 : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.SWAP(qubit1, qubit2); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.canon.applytoeachca". - @Deprecated("ApplyToEachCA(X, _)") - operation MultiX (qubits : Qubit[]) : Unit { - body (...) { - for (index in 0 .. Length(qubits) - 1) { - Microsoft.Quantum.Intrinsic.X(qubits[index]); - } - } - - adjoint self; - controlled distribute; - controlled adjoint self; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.r". - @Deprecated("Microsoft.Quantum.Intrinsic.R") - operation R(pauli : Pauli, theta : Double, qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.R(pauli, theta, qubit); - } - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.rfrac". - @Deprecated("Microsoft.Quantum.Intrinsic.RFrac") - operation RFrac(pauli : Pauli, numerator : Int, power : Int, qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.RFrac(pauli, numerator, power, qubit); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.rx". - @Deprecated("Microsoft.Quantum.Intrinsic.Rx") - operation Rx (theta : Double, qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.Rx(theta, qubit); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.ry". - @Deprecated("Microsoft.Quantum.Intrinsic.Ry") - operation Ry (theta : Double, qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.Ry(theta, qubit); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.rz". - @Deprecated("Microsoft.Quantum.Intrinsic.Rz") - operation Rz (theta : Double, qubit : Qubit) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.Rz(theta, qubit); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.r1". - @Deprecated("Microsoft.Quantum.Intrinsic.R1") - operation R1 (theta : Double, qubit : Qubit) : Unit - { - body (...) { - Microsoft.Quantum.Intrinsic.R1(theta, qubit); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.r1frac". - @Deprecated("Microsoft.Quantum.Intrinsic.R1Frac") - operation R1Frac (numerator : Int, power : Int, qubit : Qubit) : Unit - { - body (...) { - Microsoft.Quantum.Intrinsic.R1Frac(numerator, power, qubit); - } - - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.exp". - @Deprecated("Microsoft.Quantum.Intrinsic.Exp") - operation Exp (paulis : Pauli[], theta : Double, qubits : Qubit[]) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.Exp(paulis, theta, qubits); - } - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.expfrac". - @Deprecated("Microsoft.Quantum.Intrinsic.ExpFrac") - operation ExpFrac (paulis : Pauli[], numerator : Int, power : Int, qubits : Qubit[]) : Unit { - body (...) { - Microsoft.Quantum.Intrinsic.ExpFrac(paulis, numerator, power, qubits); - } - adjoint auto; - controlled auto; - controlled adjoint auto; - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.measure". - @Deprecated("Microsoft.Quantum.Intrinsic.Measure") - operation Measure(bases : Pauli[], qubits : Qubit[]) : Result { - return Microsoft.Quantum.Intrinsic.Measure(bases, qubits); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.m". - @Deprecated("Microsoft.Quantum.Intrinsic.M") - operation M (qubit : Qubit) : Result { - return Microsoft.Quantum.Intrinsic.M(qubit); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.reset". - @Deprecated("Microsoft.Quantum.Intrinsic.Reset") - operation Reset (target : Qubit) : Unit { - return Microsoft.Quantum.Intrinsic.Reset(target); - } - - /// # Deprecated - /// Please use @"microsoft.quantum.intrinsic.resetall". - @Deprecated("Microsoft.Quantum.Intrinsic.ResetAll") - operation ResetAll (qubits : Qubit[]) : Unit { - return Microsoft.Quantum.Intrinsic.ResetAll(qubits); - } - -} - diff --git a/src/Simulation/QsharpFoundation/Assert.qs b/src/Simulation/QsharpFoundation/Assert.qs index 6f36ade4d6b..30832b83767 100644 --- a/src/Simulation/QsharpFoundation/Assert.qs +++ b/src/Simulation/QsharpFoundation/Assert.qs @@ -2,67 +2,15 @@ // Licensed under the MIT License. namespace Microsoft.Quantum.Intrinsic { - /// # Summary - /// Asserts that measuring the given qubits in the given Pauli basis will - /// always have the given result. - /// - /// # Input - /// ## bases - /// A measurement effect to assert the probability of, expressed as a - /// multi-qubit Pauli operator. - /// ## qubits - /// A register on which to make the assertion. - /// ## result - /// The expected result of `Measure(bases, qubits)`. - /// ## msg - /// A message to be reported if the assertion fails. - /// - /// # Remarks - /// Note that the Adjoint and Controlled versions of this operation will not - /// check the condition. - /// - /// # See Also - /// - AssertProb + @Deprecated("Microsoft.Quantum.Diagnostics.AssertMeasurement") operation Assert (bases : Pauli[], qubits : Qubit[], result : Result, msg : String) : Unit is Adj + Ctl { - body intrinsic; + Microsoft.Quantum.Diagnostics.AssertMeasurement(bases, qubits, result, msg); } - - /// # Summary - /// Asserts that measuring the given qubits in the given Pauli basis will have the given result - /// with the given probability, within some tolerance. - /// - /// # Input - /// ## bases - /// A measurement effect to assert the probability of, expressed as a - /// multi-qubit Pauli operator. - /// ## qubits - /// A register on which to make the assertion. - /// ## result - /// An expected result of `Measure(bases, qubits)`. - /// ## prob - /// The probability with which the given result is expected. - /// ## msg - /// A message to be reported if the assertion fails. - /// - /// # Example - /// ```qsharp - /// using (register = Qubit()) { - /// H(register); - /// AssertProb([PauliZ], [register], One, 0.5, - /// "Measuring in conjugate basis did not give 50/50 results.", 1e-5); - /// } - /// ``` - /// - /// # Remarks - /// Note that the Adjoint and Controlled versions of this operation will not - /// check the condition. - /// - /// # See Also - /// - Assert + @Deprecated("Microsoft.Quantum.Diagnostics.AssertMeasurementProbability") operation AssertProb (bases : Pauli[], qubits : Qubit[], result : Result, prob : Double, msg : String, tol : Double) : Unit is Adj + Ctl { - body intrinsic; + Microsoft.Quantum.Diagnostics.AssertMeasurementProbability(bases, qubits, result, prob, msg, tol); } } \ No newline at end of file diff --git a/src/Simulation/QsharpFoundation/Diagnostics/Assert.qs b/src/Simulation/QsharpFoundation/Diagnostics/Assert.qs new file mode 100644 index 00000000000..9b0635279a9 --- /dev/null +++ b/src/Simulation/QsharpFoundation/Diagnostics/Assert.qs @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.Quantum.Diagnostics { + /// # Summary + /// Asserts that measuring the given qubits in the given Pauli basis will + /// always have the given result. + /// + /// # Input + /// ## bases + /// A measurement effect to assert the probability of, expressed as a + /// multi-qubit Pauli operator. + /// ## qubits + /// A register on which to make the assertion. + /// ## result + /// The expected result of `Measure(bases, qubits)`. + /// ## msg + /// A message to be reported if the assertion fails. + /// + /// # Remarks + /// Note that the Adjoint and Controlled versions of this operation will not + /// check the condition. + /// + /// # See Also + /// - Microsoft.Quantum.Diagnostics.AssertMeasurementProbability + operation AssertMeasurement(bases : Pauli[], qubits : Qubit[], result : Result, msg : String) : Unit + is Adj + Ctl { + body intrinsic; + } + + + /// # Summary + /// Asserts that measuring the given qubits in the given Pauli basis will have the given result + /// with the given probability, within some tolerance. + /// + /// # Input + /// ## bases + /// A measurement effect to assert the probability of, expressed as a + /// multi-qubit Pauli operator. + /// ## qubits + /// A register on which to make the assertion. + /// ## result + /// An expected result of `Measure(bases, qubits)`. + /// ## prob + /// The probability with which the given result is expected. + /// ## msg + /// A message to be reported if the assertion fails. + /// + /// # Example + /// ```qsharp + /// using (register = Qubit()) { + /// H(register); + /// AssertProb([PauliZ], [register], One, 0.5, + /// "Measuring in conjugate basis did not give 50/50 results.", 1e-5); + /// } + /// ``` + /// + /// # Remarks + /// Note that the Adjoint and Controlled versions of this operation will not + /// check the condition. + /// + /// # See Also + /// - Microsoft.Quantum.Diagnostics.AssertMeasurement + operation AssertMeasurementProbability(bases : Pauli[], qubits : Qubit[], result : Result, prob : Double, msg : String, tol : Double) : Unit + is Adj + Ctl { + body intrinsic; + } + +} diff --git a/src/Simulation/QsharpFoundation/Message.qs b/src/Simulation/QsharpFoundation/Message.qs index 5ae8f8c2cfb..2a5a920491b 100644 --- a/src/Simulation/QsharpFoundation/Message.qs +++ b/src/Simulation/QsharpFoundation/Message.qs @@ -12,7 +12,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Remarks /// The specific behavior of this function is simulator-dependent, /// but in most cases the given message will be written to the console. - function Message(msg : String) : Unit { + function Message (msg : String) : Unit { body intrinsic; } } \ No newline at end of file diff --git a/src/Simulation/QsharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj b/src/Simulation/QsharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj index b8bf50a76e1..74767a47432 100644 --- a/src/Simulation/QsharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj +++ b/src/Simulation/QsharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/QsharpFoundation/Random.qs b/src/Simulation/QsharpFoundation/Random.qs index b43b0c7fb5a..35a7239182b 100644 --- a/src/Simulation/QsharpFoundation/Random.qs +++ b/src/Simulation/QsharpFoundation/Random.qs @@ -19,7 +19,7 @@ namespace Microsoft.Quantum.Intrinsic { /// # Output /// An integer $i$ with probability $\Pr(i) = p_i / \sum_i p_i$, where $p_i$ /// is the $i$th element of `probs`. - operation Random(probs : Double[]) : Int { + operation Random (probs : Double[]) : Int { body intrinsic; } } \ No newline at end of file diff --git a/src/Simulation/RoslynWrapper/Microsoft.Quantum.RoslynWrapper.fsproj b/src/Simulation/RoslynWrapper/Microsoft.Quantum.RoslynWrapper.fsproj index 64eda827125..53e2cca58c9 100644 --- a/src/Simulation/RoslynWrapper/Microsoft.Quantum.RoslynWrapper.fsproj +++ b/src/Simulation/RoslynWrapper/Microsoft.Quantum.RoslynWrapper.fsproj @@ -37,15 +37,7 @@ - - all - runtime; build; native; contentfiles; analyzers - - - - - - + diff --git a/src/Simulation/Simulators.Tests/Circuits/Bug3758.qs b/src/Simulation/Simulators.Tests/Circuits/Bug3758.qs index 894c45cac3e..e65347a39e1 100644 --- a/src/Simulation/Simulators.Tests/Circuits/Bug3758.qs +++ b/src/Simulation/Simulators.Tests/Circuits/Bug3758.qs @@ -1,12 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace Bug3758 -{ - open Microsoft.Quantum.Primitive; +namespace Bug3758 { + open Microsoft.Quantum.Intrinsic; - function Reverse<'T> (array : 'T[]) : 'T[] - { + function Reverse<'T> (array : 'T[]) : 'T[] { let nElements = Length(array); return array[nElements-1..-1..0]; } @@ -22,43 +20,31 @@ namespace Bug3758 /// # Summary /// An example operation used for testing input transformations. - operation TransformationReferenceForward(register : Qubit[]) : Unit { - body (...) { - X(register[0]); - H(register[1]); - X(register[2]); - } - adjoint auto; - controlled auto; - controlled adjoint auto; + operation TransformationReferenceForward(register : Qubit[]) : Unit is Adj + Ctl { + X(register[0]); + H(register[1]); + X(register[2]); } /// # Summary /// An example operation used for testing input transformations. - operation TransformationReferenceReverse(register : Qubit[]) : Unit { - body (...) { - X(register[2]); - H(register[1]); - X(register[0]); - } - adjoint auto; - controlled auto; - controlled adjoint auto; + operation TransformationReferenceReverse(register : Qubit[]) : Unit is Adj + Ctl { + X(register[2]); + H(register[1]); + X(register[0]); } } -namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits -{ +namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { open Bug3758; - open Microsoft.Quantum.Extensions.Testing; + open Microsoft.Quantum.Diagnostics; operation TransformedOperationTest() : Unit { - AssertOperationsEqualReferenced( + AssertOperationsEqualReferenced(3, TransformedOperation(Reverse, TransformationReferenceReverse), - TransformationReferenceForward, - 3 + TransformationReferenceForward ); } } diff --git a/src/Simulation/Simulators.Tests/Circuits/Fail.qs b/src/Simulation/Simulators.Tests/Circuits/Fail.qs index fc6aa685f76..1f079c005eb 100644 --- a/src/Simulation/Simulators.Tests/Circuits/Fail.qs +++ b/src/Simulation/Simulators.Tests/Circuits/Fail.qs @@ -89,9 +89,11 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits { } operation AllocateQubit2 () : Unit { - using( q = Qubit() ) { + using (q = Qubit()) { Microsoft.Quantum.Intrinsic.H(q); - Microsoft.Quantum.Intrinsic.Assert([PauliZ],[q],One,""); + Microsoft.Quantum.Diagnostics.AssertMeasurement( + [PauliZ], [q], One, "" + ); } } -} \ No newline at end of file +} diff --git a/src/Simulation/Simulators.Tests/Circuits/ResourcesEstimator.qs b/src/Simulation/Simulators.Tests/Circuits/ResourcesEstimator.qs index 8d34b42448c..dd3e52fc884 100644 --- a/src/Simulation/Simulators.Tests/Circuits/ResourcesEstimator.qs +++ b/src/Simulation/Simulators.Tests/Circuits/ResourcesEstimator.qs @@ -16,4 +16,45 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests ResetAll([q[1], q[0]]); } } + + // When multiple operations are traced by resource estimator, + // it should report cumulative statistics in the end. + operation Operation_1_of_2() : Unit + { + using ((a, b) = (Qubit(), Qubit())) { + H(a); + CNOT(a, b); + T(b); + } + } + operation Operation_2_of_2() : Result + { + using ((a, b, c) = (Qubit(), Qubit(), Qubit())) { + X(a); + CNOT(a, b); + Rx(0.42, b); + CNOT(b, c); + return M(c); + } + } + + // Tests for Depth and Width lower bounds + operation DepthDifferentQubits () : Unit + { + using(q = Qubit[3]) { + T(q[0]); + T(q[1]); + T(q[2]); + T(q[0]); + } + } + operation DepthVersusWidth () : Unit + { + using(q = Qubit()) { + T(q); + } + using(q = Qubit()) { + T(q); + } + } } diff --git a/src/Simulation/Simulators.Tests/ResourcesEstimatorTests.cs b/src/Simulation/Simulators.Tests/ResourcesEstimatorTests.cs index 5fa9728a0d0..0a60328484d 100644 --- a/src/Simulation/Simulators.Tests/ResourcesEstimatorTests.cs +++ b/src/Simulation/Simulators.Tests/ResourcesEstimatorTests.cs @@ -2,9 +2,8 @@ // Licensed under the MIT License. using System; -using System.Collections.Generic; using System.Linq; -using System.Text; +using System.Data; using Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime; using Xunit; @@ -95,11 +94,86 @@ public void ToTSVTest() var cols = rows[0].Split('\t'); Assert.Equal("Metric", cols[0].Trim()); - Assert.Equal(2, cols.Length); + Assert.Equal(3, cols.Length); var cliffords = rows.First(r => r.StartsWith("QubitClifford")).Split('\t'); - Assert.Equal(2, cliffords.Length); + Assert.Equal(3, cliffords.Length); Assert.Equal("2", cliffords[1]); + } + + /// + /// Shows that T gates on different qubits are counted for depth purposes as + /// executing in parallel. + /// + [Fact] + public void DepthDifferentQubitsTest() + { + var sim = new ResourcesEstimator(); + + // using(q = Qubit[3]) { T(q[0]); T(q[1]); T(q[3]); T(q[0]); } + DepthDifferentQubits.Run(sim).Wait(); + var data = sim.Data; + + Assert.Equal(4.0, data.Rows.Find("T")["Sum"]); + Assert.Equal(3.0, data.Rows.Find("Width")["Sum"]); + Assert.Equal(2.0, data.Rows.Find("Depth")["Sum"]); + } + + /// + /// Documents that the width and depth statistics reflect independent lower + /// bounds for each (two T gates cannot be combined into a circuit of depth + /// one and width one). + /// + [Fact] + public void DepthVersusWidthTest() + { + var sim = new ResourcesEstimator(); + + // using(q = Qubit()) { T(q); } using(q = Qubit()) { T(q); } (yes, twice) + DepthVersusWidth.Run(sim).Wait(); + var data = sim.Data; + + Assert.Equal(2.0, data.Rows.Find("T")["Sum"]); + Assert.Equal(1.0, data.Rows.Find("Width")["Sum"]); + Assert.Equal(1.0, data.Rows.Find("Depth")["Sum"]); + } + + /// + /// Verifies that for multiple separately traced operations, the final + /// statistics are cumulative. + /// + [Fact] + public void VerifyTracingMultipleOperationsTest() + { + ResourcesEstimator sim = new ResourcesEstimator(); + + Operation_1_of_2.Run(sim).Wait(); + DataTable data1 = sim.Data; + + Assert.Equal(1.0, data1.Rows.Find("CNOT")["Sum"]); + Assert.Equal(1.0, data1.Rows.Find("QubitClifford")["Sum"]); + Assert.Equal(1.0, data1.Rows.Find("T")["Sum"]); + Assert.Equal(0.0, data1.Rows.Find("R")["Sum"]); + Assert.Equal(0.0, data1.Rows.Find("Measure")["Sum"]); + Assert.Equal(2.0, data1.Rows.Find("Width")["Sum"]); + + Operation_2_of_2.Run(sim).Wait(); + DataTable data2 = sim.Data; + + // Aggregated stats for both operations. + Assert.Equal(1.0 + 2.0, data2.Rows.Find("CNOT")["Sum"]); + Assert.Equal(1.0 + 1.0, data2.Rows.Find("QubitClifford")["Sum"]); + Assert.Equal(1.0 + 0.0, data2.Rows.Find("T")["Sum"]); + Assert.Equal(0.0 + 1.0, data2.Rows.Find("R")["Sum"]); + Assert.Equal(0.0 + 1.0, data2.Rows.Find("Measure")["Sum"]); + Assert.Equal(2.0 + 3.0, data2.Rows.Find("Width")["Sum"]); + Assert.Equal(System.Math.Max(2.0, 3.0), data2.Rows.Find("Width")["Max"]); + + // Run again to confirm two operations isn't the limit! + VerySimpleEstimate.Run(sim).Wait(); + DataTable data3 = sim.Data; + Assert.Equal(2.0 + 3.0 + 3.0, data3.Rows.Find("Width")["Sum"]); + Assert.Equal(3.0, data3.Rows.Find("Width")["Max"]); } } } diff --git a/src/Simulation/Simulators.Tests/StackTraceTests.cs b/src/Simulation/Simulators.Tests/StackTraceTests.cs index 48c142d7e2b..c3fead7b586 100644 --- a/src/Simulation/Simulators.Tests/StackTraceTests.cs +++ b/src/Simulation/Simulators.Tests/StackTraceTests.cs @@ -1,6 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +#nullable enable + using Xunit; using System; @@ -29,32 +31,33 @@ public StackTraceTests(ITestOutputHelper output) [Fact] public void AllocateQubit2Test() { - using (var sim = new QuantumSimulator()) + using var sim = new QuantumSimulator(); + try { - try - { - IgnorableAssert.Disable(); - QVoid res = sim.Execute(QVoid.Instance); - } - catch (ExecutionFailException) - { - StackFrame[] stackFrames = sim.CallStack; + IgnorableAssert.Disable(); + QVoid res = sim.Execute(QVoid.Instance); + } + catch (ExecutionFailException) + { + var stackFrames = sim.CallStack; - // The following assumes that Assert is on Q# stack. - Assert.Equal(2, stackFrames.Length); + // Make sure that the call stack isn't null before proceeding. + Assert.NotNull(stackFrames); - Assert.Equal("Microsoft.Quantum.Intrinsic.Assert", stackFrames[0].Callable.FullName); - Assert.Equal(namespacePrefix + "AllocateQubit2", stackFrames[1].Callable.FullName); + // The following assumes that Assert is on Q# stack. + Assert.Equal(2, stackFrames!.Length); - Assert.Equal(OperationFunctor.Body, stackFrames[0].Callable.Variant); - Assert.Equal(OperationFunctor.Body, stackFrames[1].Callable.Variant); + Assert.Equal("Microsoft.Quantum.Diagnostics.AssertMeasurement", stackFrames[0].Callable.FullName); + Assert.Equal(namespacePrefix + "AllocateQubit2", stackFrames[1].Callable.FullName); - Assert.Equal(94, stackFrames[1].FailedLineNumber); - } - finally - { - IgnorableAssert.Enable(); - } + Assert.Equal(OperationFunctor.Body, stackFrames[0].Callable.Variant); + Assert.Equal(OperationFunctor.Body, stackFrames[1].Callable.Variant); + + Assert.Equal(94, stackFrames[1].FailedLineNumber); + } + finally + { + IgnorableAssert.Enable(); } } diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj b/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj new file mode 100644 index 00000000000..89f9b7e7bf4 --- /dev/null +++ b/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library with Spaces.csproj @@ -0,0 +1,25 @@ + + + netstandard2.1 + false + false + + + true + + + + + + + + + + + + + diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library.qs b/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library.qs new file mode 100644 index 00000000000..eebe352cb30 --- /dev/null +++ b/src/Simulation/Simulators.Tests/TestProjects/Library with Spaces/Library.qs @@ -0,0 +1,5 @@ +namespace LibraryWithSpaces { + function HelloQ() : String { + return "Hello quantum world!"; + } +} diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj b/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj index 8e69c0a388d..2da5c023bb3 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/Library1/Library1.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj b/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj index 8e69c0a388d..2da5c023bb3 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/Library2/Library2.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj b/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj index 9326805e5a9..85fe87c7403 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/QsharpExe/QsharpExe.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/Facts.qs b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/Facts.qs new file mode 100644 index 00000000000..880bdf81a85 --- /dev/null +++ b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/Facts.qs @@ -0,0 +1,37 @@ +namespace Microsoft.Quantum.Testing { + internal function FactI(expected : Int, got : Int) : Unit { + if (expected != got) { + fail $"Expected: {expected}, got: {got}"; + } + } + + internal function FactS(expected : String, got : String) : Unit { + if (expected != got) { + fail $"Expected: {expected}, got: {got}"; + } + } + + internal function FactMyInt1(expected : Int, got : Library1.MyInt) : Unit { + if (expected != got::Value1) { + fail $"Expected: {expected}, got: {got::Value1}"; + } + } + + internal function FactMyInt2(expected : Int, got : Library2.MyInt) : Unit { + if (expected != got::Value2) { + fail $"Expected: {expected}, got: {got::Value2}"; + } + } + + internal function FactMyString1(expected : String, got : Microsoft.Quantum.Library.MyString) : Unit { + if (expected != got::Text) { + fail $"Expected: {expected}, got: {got::Text}"; + } + } + + internal function FactMyString2(expected : String, got : Library2.MyString) : Unit { + if (expected != got::Text) { + fail $"Expected: {expected}, got: {got::Text}"; + } + } +} diff --git a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/SpaceTests.qs b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/SpaceTests.qs new file mode 100644 index 00000000000..2faa5616e2b --- /dev/null +++ b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/SpaceTests.qs @@ -0,0 +1,9 @@ +namespace Microsoft.Quantum.Testing.SpacesInFileName { + open Microsoft.Quantum.Diagnostics; + open Microsoft.Quantum.Testing; + + @Test("QuantumSimulator") + function LibraryWithSpacesTest() : Unit { + FactS("Hello quantum world!", LibraryWithSpaces.HelloQ()); + } +} diff --git a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/Tests.qs b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/TestNameTests.qs similarity index 52% rename from src/Simulation/Simulators.Tests/TestProjects/UnitTests/Tests.qs rename to src/Simulation/Simulators.Tests/TestProjects/UnitTests/TestNameTests.qs index 008f2c9f646..68a3ee38845 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/Tests.qs +++ b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/TestNameTests.qs @@ -2,43 +2,7 @@ open Microsoft.Quantum.Diagnostics; open Microsoft.Quantum.Intrinsic; - - internal function FactI(expected : Int, got : Int) : Unit { - if (expected != got) { - fail $"Expected: {expected}, got: {got}"; - } - } - - internal function FactS(expected : String, got : String) : Unit { - if (expected != got) { - fail $"Expected: {expected}, got: {got}"; - } - } - - internal function FactMyInt1(expected : Int, got : Library1.MyInt) : Unit { - if (expected != got::Value1) { - fail $"Expected: {expected}, got: {got::Value1}"; - } - } - - internal function FactMyInt2(expected : Int, got : Library2.MyInt) : Unit { - if (expected != got::Value2) { - fail $"Expected: {expected}, got: {got::Value2}"; - } - } - - internal function FactMyString1(expected : String, got : Microsoft.Quantum.Library.MyString) : Unit { - if (expected != got::Text) { - fail $"Expected: {expected}, got: {got::Text}"; - } - } - - internal function FactMyString2(expected : String, got : Library2.MyString) : Unit { - if (expected != got::Text) { - fail $"Expected: {expected}, got: {got::Text}"; - } - } - + open Microsoft.Quantum.Testing; @Test("QuantumSimulator") operation BothCallables () : Unit { diff --git a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj index 73c103678c0..5057578a2a9 100644 --- a/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj +++ b/src/Simulation/Simulators.Tests/TestProjects/UnitTests/UnitTests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -15,6 +15,7 @@ + diff --git a/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj b/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj index cc6001ef292..ab4bbc9e837 100644 --- a/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj +++ b/src/Simulation/Simulators.Tests/Tests.Microsoft.Quantum.Simulators.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj b/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj index 167a6619277..8229c9e9bc7 100644 --- a/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj +++ b/src/Simulation/Simulators/Microsoft.Quantum.Simulators.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Simulation/Simulators/QCTraceSimulator/InterfaceUtils.cs b/src/Simulation/Simulators/QCTraceSimulator/InterfaceUtils.cs index 79395f62ec6..f3beba01330 100644 --- a/src/Simulation/Simulators/QCTraceSimulator/InterfaceUtils.cs +++ b/src/Simulation/Simulators/QCTraceSimulator/InterfaceUtils.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.Collections.Generic; using System.Diagnostics; using Microsoft.Quantum.Simulation.Core; @@ -73,5 +74,19 @@ public static partial class Extensions { return InterfaceType(t, typeof(IControllable<>)); } + + internal static IEnumerable SelectAggregates( + this IEnumerable source, + Func aggregate, + TResult initial = default + ) + { + var acc = initial; + foreach (var element in source) + { + acc = aggregate(acc, element); + yield return acc; + } + } } } \ No newline at end of file diff --git a/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Primitive.Assert.cs b/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Primitive.Assert.cs index bcbd49b948a..71357de0bd7 100644 --- a/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Primitive.Assert.cs +++ b/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Primitive.Assert.cs @@ -9,7 +9,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati public partial class QCTraceSimulatorImpl { - public class TracerAssert : Intrinsic.Assert + public class TracerAssert : Microsoft.Quantum.Diagnostics.AssertMeasurement { private readonly QCTraceSimulatorCore core; public TracerAssert(QCTraceSimulatorImpl m) : base(m) diff --git a/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Primitive.AssertProb.cs b/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Primitive.AssertProb.cs index 511682661ed..705d5d3ae1d 100644 --- a/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Primitive.AssertProb.cs +++ b/src/Simulation/Simulators/QCTraceSimulator/QCTraceSimulator.Primitive.AssertProb.cs @@ -9,7 +9,7 @@ namespace Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementati public partial class QCTraceSimulatorImpl { - public class TracerAssertProb : Intrinsic.AssertProb + public class TracerAssertProb : Microsoft.Quantum.Diagnostics.AssertMeasurementProbability { private readonly QCTraceSimulatorCore core; public TracerAssertProb(QCTraceSimulatorImpl m) : base(m){ diff --git a/src/Simulation/Simulators/QCTraceSimulator/Utils.cs b/src/Simulation/Simulators/QCTraceSimulator/Utils.cs index 203173c3137..9f991e7ed0c 100644 --- a/src/Simulation/Simulators/QCTraceSimulator/Utils.cs +++ b/src/Simulation/Simulators/QCTraceSimulator/Utils.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Collections.Generic; +using System.Linq; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime; @@ -214,32 +216,36 @@ static class SimulatorsUtils /// Number between Zero and one, uniformly distributed public static long SampleDistribution(IQArray unnormalizedDistribution, double uniformZeroOneSample) { - double total = 0.0; - foreach (double prob in unnormalizedDistribution) + if (unnormalizedDistribution.Any(prob => prob < 0.0)) { - if (prob < 0) - { - throw new ExecutionFailException("Random expects array of non-negative doubles."); - } - total += prob; + throw new ExecutionFailException("Random expects array of non-negative doubles."); } + var total = unnormalizedDistribution.Sum(); if (total == 0) { throw new ExecutionFailException("Random expects array of non-negative doubles with positive sum."); } - double sample = uniformZeroOneSample * total; - double sum = unnormalizedDistribution[0]; - for (int i = 0; i < unnormalizedDistribution.Length - 1; ++i) - { - if (sum >= sample) - { - return i; - } - sum += unnormalizedDistribution[i]; - } - return unnormalizedDistribution.Length; + var sample = uniformZeroOneSample * total; + + return unnormalizedDistribution + // Get the unnormalized CDF of the distribution. + .SelectAggregates((double acc, double x) => acc + x) + // Look for the first index at which the CDF is bigger + // than the random sample of 𝑈(0, 1) that we were given + // as a parameter. + .Select((cumulativeProb, idx) => (cumulativeProb, idx)) + .Where(item => item.cumulativeProb >= sample) + // Cast that index to long, and default to returning + // the last item. + .Select( + item => (long)item.idx + ) + .DefaultIfEmpty( + unnormalizedDistribution.Length - 1 + ) + .First(); } } } diff --git a/src/Simulation/Simulators/QuantumProcessor/Assert.cs b/src/Simulation/Simulators/QuantumProcessor/Assert.cs index 50f230e89ee..a0badd62007 100644 --- a/src/Simulation/Simulators/QuantumProcessor/Assert.cs +++ b/src/Simulation/Simulators/QuantumProcessor/Assert.cs @@ -9,7 +9,7 @@ namespace Microsoft.Quantum.Simulation.QuantumProcessor { public partial class QuantumProcessorDispatcher { - public class QuantumProcessorDispatcherAssert : Quantum.Intrinsic.Assert + public class QuantumProcessorDispatcherAssert : Microsoft.Quantum.Diagnostics.AssertMeasurement { private QuantumProcessorDispatcher Simulator { get; } diff --git a/src/Simulation/Simulators/QuantumProcessor/AssertProb.cs b/src/Simulation/Simulators/QuantumProcessor/AssertProb.cs index 9a86fb29fca..9f4d87e085e 100644 --- a/src/Simulation/Simulators/QuantumProcessor/AssertProb.cs +++ b/src/Simulation/Simulators/QuantumProcessor/AssertProb.cs @@ -9,7 +9,7 @@ namespace Microsoft.Quantum.Simulation.QuantumProcessor { public partial class QuantumProcessorDispatcher { - public class QuantumProcessorDispatcherAssertProb : Quantum.Intrinsic.AssertProb + public class QuantumProcessorDispatcherAssertProb : Microsoft.Quantum.Diagnostics.AssertMeasurementProbability { private QuantumProcessorDispatcher Simulator { get; } diff --git a/src/Simulation/Simulators/QuantumSimulator/Assert.cs b/src/Simulation/Simulators/QuantumSimulator/Assert.cs index d0936509470..69d1b035d69 100644 --- a/src/Simulation/Simulators/QuantumSimulator/Assert.cs +++ b/src/Simulation/Simulators/QuantumSimulator/Assert.cs @@ -12,7 +12,7 @@ namespace Microsoft.Quantum.Simulation.Simulators { public partial class QuantumSimulator { - public class QSimAssert : Quantum.Intrinsic.Assert + public class QSimAssert : Microsoft.Quantum.Diagnostics.AssertMeasurement { [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "JointEnsembleProbability")] private static extern double JointEnsembleProbability(uint id, uint n, Pauli[] b, uint[] q); diff --git a/src/Simulation/Simulators/QuantumSimulator/AssertProb.cs b/src/Simulation/Simulators/QuantumSimulator/AssertProb.cs index 8f93eea3b31..39e3901e592 100644 --- a/src/Simulation/Simulators/QuantumSimulator/AssertProb.cs +++ b/src/Simulation/Simulators/QuantumSimulator/AssertProb.cs @@ -12,7 +12,7 @@ namespace Microsoft.Quantum.Simulation.Simulators { public partial class QuantumSimulator { - public class QSimAssertProb : Quantum.Intrinsic.AssertProb + public class QSimAssertProb : Microsoft.Quantum.Diagnostics.AssertMeasurementProbability { [DllImport(QSIM_DLL_NAME, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl, EntryPoint = "JointEnsembleProbability")] private static extern double JointEnsembleProbability(uint id, uint n, Pauli[] b, uint[] q); diff --git a/src/Simulation/Simulators/ResourcesEstimator/ResourcesEstimator.cs b/src/Simulation/Simulators/ResourcesEstimator/ResourcesEstimator.cs index ec0e80ddef1..d08847898cf 100644 --- a/src/Simulation/Simulators/ResourcesEstimator/ResourcesEstimator.cs +++ b/src/Simulation/Simulators/ResourcesEstimator/ResourcesEstimator.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. using System; -using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Linq; @@ -113,6 +112,7 @@ public virtual DataTable Data table.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "Metric" }); table.Columns.Add(new DataColumn { DataType = typeof(double), ColumnName = "Sum" }); + table.Columns.Add(new DataColumn { DataType = typeof(double), ColumnName = "Max" }); table.PrimaryKey = new DataColumn[] { table.Columns[0] }; foreach (var l in CoreConfig.Listeners) @@ -121,11 +121,9 @@ public virtual DataTable Data if (l is ICallGraphStatistics collector) { var results = collector.Results.ToTable(); - Debug.Assert(results.rows.Count() == 1); Debug.Assert(results.keyColumnNames.Length > 2 && results.keyColumnNames[2] == "Caller"); - var root = results.rows.FirstOrDefault(r => r.KeyRow[2] == CallGraphEdge.CallGraphRootHashed); - + var roots = results.rows.Where(r => r.KeyRow[2] == CallGraphEdge.CallGraphRootHashed); var s_idx = Array.FindIndex(results.statisticsNames, n => n == "Sum"); for (var m_idx = 0; m_idx < results.metricNames.Length; m_idx++) @@ -133,12 +131,21 @@ public virtual DataTable Data var label = GetMetricLabel(results.metricNames[m_idx]); if (label == null) continue; - var row = table.NewRow(); + DataRow row = table.NewRow(); row["Metric"] = label; if (m_idx >= 0 && s_idx >= 0) - { - row["Sum"] = root.DataRow[m_idx, s_idx]; + { + Double sum = 0; + Double max = 0; // all our metrics are positive + foreach (var r in roots) + { + Double metric_value = r.DataRow[m_idx, s_idx]; + sum += metric_value; + max = System.Math.Max(max, metric_value); + } + row["Sum"] = sum; + row["Max"] = max; } table.Rows.Add(row); diff --git a/src/Simulation/Simulators/ToffoliSimulator/Assert.cs b/src/Simulation/Simulators/ToffoliSimulator/Assert.cs index 1d00d159ea1..13c71ead4d9 100644 --- a/src/Simulation/Simulators/ToffoliSimulator/Assert.cs +++ b/src/Simulation/Simulators/ToffoliSimulator/Assert.cs @@ -12,7 +12,7 @@ public partial class ToffoliSimulator /// /// Implementation of the Assert operation for the Toffoli simulator. /// - public class Assert : Intrinsic.Assert + public class Assert : Microsoft.Quantum.Diagnostics.AssertMeasurement { private ToffoliSimulator simulator; diff --git a/src/Simulation/Simulators/ToffoliSimulator/AssertProb.cs b/src/Simulation/Simulators/ToffoliSimulator/AssertProb.cs index 29228e9b604..3ed31f98369 100644 --- a/src/Simulation/Simulators/ToffoliSimulator/AssertProb.cs +++ b/src/Simulation/Simulators/ToffoliSimulator/AssertProb.cs @@ -13,7 +13,7 @@ public partial class ToffoliSimulator /// /// Implementation of the AssertProb operation for the Toffoli simulator. /// - public class AssertProb : Intrinsic.AssertProb + public class AssertProb : Microsoft.Quantum.Diagnostics.AssertMeasurementProbability { private ToffoliSimulator simulator;