From d143ae5081518cd50cfe88c0430d72a42cb2ba32 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 10 Feb 2021 18:31:58 -0800 Subject: [PATCH 01/43] Add %simulate_noise and %noise_model magic commands. --- src/AzureClient/AzureClient.csproj | 2 +- src/Core/Core.csproj | 8 +- .../ExecutionPathTracer.csproj | 2 +- src/Jupyter/Extensions.cs | 50 +++++++++++ .../NoiseModelSource/INoiseModelSource.cs | 20 +++++ .../NoiseModelSource/NoiseModelSource.cs | 20 +++++ .../Visualization/OpenSystemsEncoders.cs | 79 ++++++++++++++++ src/Kernel/Extensions.cs | 2 + src/Kernel/Magic/NoiseModel.cs | 78 ++++++++++++++++ src/Kernel/Magic/SimulateNoise.cs | 89 +++++++++++++++++++ .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +- .../Mock.Standard/Mock.Standard.csproj | 4 +- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +- src/Tool/appsettings.json | 32 +++---- 16 files changed, 368 insertions(+), 30 deletions(-) create mode 100644 src/Jupyter/NoiseModelSource/INoiseModelSource.cs create mode 100644 src/Jupyter/NoiseModelSource/NoiseModelSource.cs create mode 100644 src/Jupyter/Visualization/OpenSystemsEncoders.cs create mode 100644 src/Kernel/Magic/NoiseModel.cs create mode 100644 src/Kernel/Magic/SimulateNoise.cs diff --git a/src/AzureClient/AzureClient.csproj b/src/AzureClient/AzureClient.csproj index 0f25cfb667..2f22563f26 100644 --- a/src/AzureClient/AzureClient.csproj +++ b/src/AzureClient/AzureClient.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 294cd351fc..0391ae1a7e 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index 45fe4bb81d..355c521715 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/Jupyter/Extensions.cs b/src/Jupyter/Extensions.cs index a37fd701c1..87dd5b34aa 100644 --- a/src/Jupyter/Extensions.cs +++ b/src/Jupyter/Extensions.cs @@ -7,12 +7,14 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text.RegularExpressions; using Microsoft.Jupyter.Core; using Microsoft.Quantum.Simulation.Common; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; using Newtonsoft.Json; +using NumSharp; namespace Microsoft.Quantum.IQSharp.Jupyter { @@ -275,5 +277,53 @@ public static T DecodeParameter(this Dictionary parameters, s } return JsonConvert.DeserializeObject(parameterValue, type) ?? defaultValue; } + + internal static string AsLaTeXMatrixOfComplex(this NDArray array) => + // NB: Assumes 𝑛 × 𝑛 × 2 array, where the trailing index is + // [real, imag]. + // TODO: Consolidate with logic at: + // https://github.com/microsoft/QuantumLibraries/blob/505fc27383c9914c3e1f60fb63d0acfe60b11956/Visualization/src/DisplayableUnitaryEncoders.cs#L43 + string.Join( + "\\\\\n", + Enumerable + .Range(0, array.Shape[0]) + .Select( + idxRow => string.Join(" & ", + Enumerable + .Range(0, array.Shape[1]) + .Select( + idxCol => $"{array[idxRow, idxCol, 0]} + {array[idxRow, idxCol, 1]} i" + ) + ) + ) + ); + + internal static IEnumerable IterateOverLeftmostIndex(this NDArray array) + { + foreach (var idx in Enumerable.Range(0, array.shape[0])) + { + yield return array[idx, Slice.Ellipsis]; + } + } + + internal static string AsTextMatrixOfComplex(this NDArray array, string rowSep = "\n") => + // NB: Assumes 𝑛 × 𝑛 × 2 array, where the trailing index is + // [real, imag]. + // TODO: Consolidate with logic at: + // https://github.com/microsoft/QuantumLibraries/blob/505fc27383c9914c3e1f60fb63d0acfe60b11956/Visualization/src/DisplayableUnitaryEncoders.cs#L43 + "[" + rowSep + string.Join( + rowSep, + Enumerable + .Range(0, array.Shape[0]) + .Select( + idxRow => "[" + string.Join(", ", + Enumerable + .Range(0, array.Shape[1]) + .Select( + idxCol => $"{array[idxRow, idxCol, 0]} + {array[idxRow, idxCol, 1]} i" + ) + ) + "]" + ) + ) + rowSep + "]"; } } diff --git a/src/Jupyter/NoiseModelSource/INoiseModelSource.cs b/src/Jupyter/NoiseModelSource/INoiseModelSource.cs new file mode 100644 index 0000000000..95b350469a --- /dev/null +++ b/src/Jupyter/NoiseModelSource/INoiseModelSource.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT License. + +#nullable enable + +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Quantum.Experimental +{ + + public interface INoiseModelSource + { + NoiseModel? NoiseModel { get; set; } + } + +} diff --git a/src/Jupyter/NoiseModelSource/NoiseModelSource.cs b/src/Jupyter/NoiseModelSource/NoiseModelSource.cs new file mode 100644 index 0000000000..91519251af --- /dev/null +++ b/src/Jupyter/NoiseModelSource/NoiseModelSource.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT License. + +#nullable enable + +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Microsoft.Quantum.Experimental +{ + + public interface NoiseModelSource : INoiseModelSource + { + NoiseModel? NoiseModel { get; set; } + } + +} diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs new file mode 100644 index 0000000000..b1ce291a52 --- /dev/null +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +using NumSharp; +using System.Linq; +using System.Text.Json; +using Microsoft.Jupyter.Core; +using Microsoft.Quantum.IQSharp.Jupyter; + +namespace Microsoft.Quantum.Experimental +{ + // TODO: add display encoders for other formats. + public class MixedStateToHtmlDisplayEncoder : IResultEncoder + { + /// + public string MimeType => MimeTypes.Html; + + public EncodedData? Encode(object displayable) + { + if (displayable is MixedState state) + { + return $@" + + + + + + + + + + + +
Mixed state
# of qubits{state.NQubits}
State data + $$ + \left( + \begin{{matrix}} + {state.Data.AsLaTeXMatrixOfComplex()} + \end{{matrix}} + \right) + $$ +
+ " + .ToEncodedData(); + } + else return null; + } + } + + public class NoiseModelToHtmlDisplayEncoder : IResultEncoder + { + /// + public string MimeType => MimeTypes.Html; + + public EncodedData? Encode(object displayable) + { + if (displayable is NoiseModel noiseModel) + { + return $@" + + + + + +
Noise model
Initial state + + $$ + \left( \begin{{matrix}} + {(noiseModel.InitialState as MixedState)?.Data?.AsLaTeXMatrixOfComplex() ?? ""} + \end{{matrix}} \right) +
+ ".ToEncodedData(); + } + else return null; + } + } +} diff --git a/src/Kernel/Extensions.cs b/src/Kernel/Extensions.cs index 05bf5bc7c6..e567e9e37f 100644 --- a/src/Kernel/Extensions.cs +++ b/src/Kernel/Extensions.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Jupyter.Core; using Microsoft.Jupyter.Core.Protocol; +using Microsoft.Quantum.Experimental; using Microsoft.Quantum.IQSharp.Jupyter; using Microsoft.Quantum.QsCompiler.SyntaxTokens; using Microsoft.Quantum.QsCompiler.SyntaxTree; @@ -33,6 +34,7 @@ public static void AddIQSharpKernel(this IServiceCollection services) services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); } internal static void RenderExecutionPath(this ExecutionPathTracer.ExecutionPathTracer tracer, diff --git a/src/Kernel/Magic/NoiseModel.cs b/src/Kernel/Magic/NoiseModel.cs new file mode 100644 index 0000000000..4a34dcca73 --- /dev/null +++ b/src/Kernel/Magic/NoiseModel.cs @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +using System; +using System.IO; +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Microsoft.Quantum.IQSharp; +using Microsoft.Quantum.IQSharp.Common; +using Microsoft.Quantum.IQSharp.Jupyter; +using Microsoft.Quantum.Simulation.Core; +using Microsoft.Quantum.Simulation.Simulators; +using System.Text.Json; +using Microsoft.Extensions.Logging; + +namespace Microsoft.Quantum.Experimental +{ + public class NoiseModelMagic : AbstractMagic + { + private ILogger? logger = null; + private INoiseModelSource NoiseModelSource; + + /// + /// Allows for querying noise models and for loading new noise models. + /// + public NoiseModelMagic(INoiseModelSource noiseModelSource, ILogger logger) : base( + "noise_model", + new Microsoft.Jupyter.Core.Documentation + { + Summary = "TODO", + Description = "TODO", + Examples = new string[] + { + } + }) + { + this.NoiseModelSource = noiseModelSource; + } + + /// + public override ExecutionResult Run(string input, IChannel channel) + { + var parts = input.Trim().Split(" ", 2); + var command = parts[0]; + if (command.Trim() == "--save") + { + if (NoiseModelSource.NoiseModel == null) + { + channel.Stderr("No noise model set; nothing to save."); + } + else + { + var filename = parts[1]; + File.WriteAllText(filename, JsonSerializer.Serialize(NoiseModelSource.NoiseModel)); + } + } + else if (command.Trim() == "--load") + { + var filename = parts[1]; + NoiseModelSource.NoiseModel = JsonSerializer.Deserialize(File.ReadAllText(filename)); + } + else if (input.Trim().StartsWith("{")) + { + // Parse the input as JSON. + NoiseModelSource.NoiseModel = JsonSerializer.Deserialize(input.Trim()); + } + else + { + // Just return the existing noise model. + return NoiseModelSource.NoiseModel.ToExecutionResult(); + } + + return ExecuteStatus.Ok.ToExecutionResult(); + } + } +} diff --git a/src/Kernel/Magic/SimulateNoise.cs b/src/Kernel/Magic/SimulateNoise.cs new file mode 100644 index 0000000000..bfe67849f1 --- /dev/null +++ b/src/Kernel/Magic/SimulateNoise.cs @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#nullable enable + +using System; +using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Jupyter.Core; +using Microsoft.Quantum.IQSharp; +using Microsoft.Quantum.IQSharp.Common; +using Microsoft.Quantum.IQSharp.Jupyter; +using Microsoft.Quantum.Simulation.Core; +using Microsoft.Quantum.Simulation.Simulators; + +namespace Microsoft.Quantum.Experimental +{ + public class SimulateNoiseMagic : AbstractMagic + { + private const string ParameterNameOperationName = "__operationName__"; + private ILogger? Logger = null; + private readonly INoiseModelSource NoiseModelSource; + + /// + /// Constructs a new magic command given a resolver used to find + /// operations and functions, and a configuration source used to set + /// configuration options. + /// + public SimulateNoiseMagic(ISymbolResolver resolver, IConfigurationSource configurationSource, INoiseModelSource noiseModelSource, ILogger logger) : base( + "simulate_noise", + new Microsoft.Jupyter.Core.Documentation + { + Summary = "TODO", + Description = "TODO", + Examples = new string[] + { + } + }) + { + this.SymbolResolver = resolver; + this.ConfigurationSource = configurationSource; + this.Logger = logger; + this.NoiseModelSource = noiseModelSource; + } + + /// + /// The symbol resolver used by this magic command to find + /// operations or functions to be simulated. + /// + public ISymbolResolver SymbolResolver { get; } + + /// + /// The configuration source used by this magic command to control + /// simulation options (e.g.: dump formatting options). + /// + public IConfigurationSource ConfigurationSource { get; } + + /// + public override ExecutionResult Run(string input, IChannel channel) => + RunAsync(input, channel).Result; + + /// + /// Simulates an operation given a string with its name and a JSON + /// encoding of its arguments. + /// + public async Task RunAsync(string input, IChannel channel) + { + var inputParameters = ParseInputParameters(input, firstParameterInferredName: ParameterNameOperationName); + + var name = inputParameters.DecodeParameter(ParameterNameOperationName); + var symbol = SymbolResolver.Resolve(name) as dynamic; // FIXME: Should be IQSharpSymbol. + if (symbol == null) throw new InvalidOperationException($"Invalid operation name: {name}"); + + var qsim = new OpenSystemsSimulator(); + if (NoiseModelSource.NoiseModel != null) + { + qsim.NoiseModel = NoiseModelSource.NoiseModel; + } + Logger?.LogDebug("Simulating with noise model: {NoiseModel}", JsonSerializer.Serialize(NoiseModelSource.NoiseModel)); + qsim.DisableLogToConsole(); + qsim.OnLog += channel.Stdout; + qsim.OnDisplayableDiagnostic += channel.Display; + var operation = symbol.Operation as OperationInfo; + var value = await operation.RunAsync(qsim, inputParameters); + return value.ToExecutionResult(); + } + } +} diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index 8ded1a931d..deccaa0b18 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index 8ded1a931d..deccaa0b18 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index 6f988bd966..c423ea766b 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 4de79a7419..659dd51a9b 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index 94c857aa52..7abaffd38c 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 361c65683e..6d2587340e 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.15.2101126099-alpha", + "Microsoft.Quantum.Compiler::0.15.210223161-alpha", - "Microsoft.Quantum.CsharpGeneration::0.15.2101126099-alpha", - "Microsoft.Quantum.Development.Kit::0.15.2101126099-alpha", - "Microsoft.Quantum.Simulators::0.15.2101126099-alpha", - "Microsoft.Quantum.Xunit::0.15.2101126099-alpha", + "Microsoft.Quantum.CsharpGeneration::0.15.210223161-alpha", + "Microsoft.Quantum.Development.Kit::0.15.210223161-alpha", + "Microsoft.Quantum.Simulators::0.15.210223161-alpha", + "Microsoft.Quantum.Xunit::0.15.210223161-alpha", - "Microsoft.Quantum.Standard::0.15.2101126099-alpha", - "Microsoft.Quantum.Standard.Visualization::0.15.2101126099-alpha", - "Microsoft.Quantum.Chemistry::0.15.2101126099-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.15.2101126099-alpha", - "Microsoft.Quantum.MachineLearning::0.15.2101126099-alpha", - "Microsoft.Quantum.Numerics::0.15.2101126099-alpha", + "Microsoft.Quantum.Standard::0.15.210223161-alpha", + "Microsoft.Quantum.Standard.Visualization::0.15.210223161-alpha", + "Microsoft.Quantum.Chemistry::0.15.210223161-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.15.210223161-alpha", + "Microsoft.Quantum.MachineLearning::0.15.210223161-alpha", + "Microsoft.Quantum.Numerics::0.15.210223161-alpha", - "Microsoft.Quantum.Katas::0.15.2101126099-alpha", + "Microsoft.Quantum.Katas::0.15.210223161-alpha", - "Microsoft.Quantum.Research::0.15.2101126099-alpha", + "Microsoft.Quantum.Research::0.15.210223161-alpha", - "Microsoft.Quantum.Providers.IonQ::0.15.2101126099-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.15.2101126099-alpha", - "Microsoft.Quantum.Providers.QCI::0.15.2101126099-alpha" + "Microsoft.Quantum.Providers.IonQ::0.15.210223161-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.15.210223161-alpha", + "Microsoft.Quantum.Providers.QCI::0.15.210223161-alpha" ] } From b7c2f3a6ef0afe0808bd1fc3b36b26e8980bcf06 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 10 Feb 2021 18:32:26 -0800 Subject: [PATCH 02/43] Guard new magic behind experimental. --- src/Kernel/Magic/NoiseModel.cs | 2 +- src/Kernel/Magic/SimulateNoise.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Kernel/Magic/NoiseModel.cs b/src/Kernel/Magic/NoiseModel.cs index 4a34dcca73..451fdf99fe 100644 --- a/src/Kernel/Magic/NoiseModel.cs +++ b/src/Kernel/Magic/NoiseModel.cs @@ -26,7 +26,7 @@ public class NoiseModelMagic : AbstractMagic /// Allows for querying noise models and for loading new noise models. /// public NoiseModelMagic(INoiseModelSource noiseModelSource, ILogger logger) : base( - "noise_model", + "experimental.noise_model", new Microsoft.Jupyter.Core.Documentation { Summary = "TODO", diff --git a/src/Kernel/Magic/SimulateNoise.cs b/src/Kernel/Magic/SimulateNoise.cs index bfe67849f1..90f8cbfc43 100644 --- a/src/Kernel/Magic/SimulateNoise.cs +++ b/src/Kernel/Magic/SimulateNoise.cs @@ -28,7 +28,7 @@ public class SimulateNoiseMagic : AbstractMagic /// configuration options. /// public SimulateNoiseMagic(ISymbolResolver resolver, IConfigurationSource configurationSource, INoiseModelSource noiseModelSource, ILogger logger) : base( - "simulate_noise", + "experimental.simulate_noise", new Microsoft.Jupyter.Core.Documentation { Summary = "TODO", From f09d5916047dfaa55109e3032a9eaa1d1977c54f Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 12 Feb 2021 08:32:15 -0800 Subject: [PATCH 03/43] Fix to noise model source, use noise_model::ideal(). --- src/Jupyter/NoiseModelSource/INoiseModelSource.cs | 2 +- src/Jupyter/NoiseModelSource/NoiseModelSource.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Jupyter/NoiseModelSource/INoiseModelSource.cs b/src/Jupyter/NoiseModelSource/INoiseModelSource.cs index 95b350469a..5ea1fe8c32 100644 --- a/src/Jupyter/NoiseModelSource/INoiseModelSource.cs +++ b/src/Jupyter/NoiseModelSource/INoiseModelSource.cs @@ -14,7 +14,7 @@ namespace Microsoft.Quantum.Experimental public interface INoiseModelSource { - NoiseModel? NoiseModel { get; set; } + NoiseModel NoiseModel { get; set; } } } diff --git a/src/Jupyter/NoiseModelSource/NoiseModelSource.cs b/src/Jupyter/NoiseModelSource/NoiseModelSource.cs index 91519251af..a30859252a 100644 --- a/src/Jupyter/NoiseModelSource/NoiseModelSource.cs +++ b/src/Jupyter/NoiseModelSource/NoiseModelSource.cs @@ -12,9 +12,9 @@ namespace Microsoft.Quantum.Experimental { - public interface NoiseModelSource : INoiseModelSource + public class NoiseModelSource : INoiseModelSource { - NoiseModel? NoiseModel { get; set; } + public NoiseModel NoiseModel { get; set; } = NoiseModel.Ideal; } } From c93a872976692964f247b9faa8f53ee7eac4736b Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 12 Feb 2021 15:17:00 -0800 Subject: [PATCH 04/43] Bump version and begin adding more documentation. --- src/AzureClient/AzureClient.csproj | 2 +- src/Core/Core.csproj | 8 ++-- src/Jupyter/Extensions.cs | 27 -------------- src/Kernel/Magic/NoiseModel.cs | 36 +++++++++++++++++- src/Kernel/Magic/SimulateNoise.cs | 37 ++++++++++++++++++- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +- .../Mock.Standard/Mock.Standard.csproj | 4 +- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +- 10 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/AzureClient/AzureClient.csproj b/src/AzureClient/AzureClient.csproj index 2f22563f26..7cc7e2843b 100644 --- a/src/AzureClient/AzureClient.csproj +++ b/src/AzureClient/AzureClient.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 0391ae1a7e..8bdbadc565 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/Jupyter/Extensions.cs b/src/Jupyter/Extensions.cs index 87dd5b34aa..4100a7ed7e 100644 --- a/src/Jupyter/Extensions.cs +++ b/src/Jupyter/Extensions.cs @@ -168,33 +168,6 @@ public static T WithStackTraceDisplay(this T simulator, IChannel channel) return simulator; } - /// - /// Removes common indents from each line in a string, - /// similarly to Python's textwrap.dedent() function. - /// - public static string Dedent(this string text) - { - // First, start by finding the length of common indents, - // disregarding lines that are only whitespace. - var leadingWhitespaceRegex = new Regex(@"^[ \t]*"); - var minWhitespace = int.MaxValue; - foreach (var line in text.Split("\n")) - { - if (!string.IsNullOrWhiteSpace(line)) - { - var match = leadingWhitespaceRegex.Match(line); - minWhitespace = match.Success - ? System.Math.Min(minWhitespace, match.Value.Length) - : minWhitespace = 0; - } - } - - // We can use that to build a new regex that strips - // out common indenting. - var leftTrimRegex = new Regex(@$"^[ \t]{{{minWhitespace}}}", RegexOptions.Multiline); - return leftTrimRegex.Replace(text, ""); - } - /// /// Retrieves and JSON-decodes the value for the given parameter name. /// diff --git a/src/Kernel/Magic/NoiseModel.cs b/src/Kernel/Magic/NoiseModel.cs index 451fdf99fe..b8bbb18563 100644 --- a/src/Kernel/Magic/NoiseModel.cs +++ b/src/Kernel/Magic/NoiseModel.cs @@ -29,10 +29,42 @@ public NoiseModelMagic(INoiseModelSource noiseModelSource, ILogger **⚠ WARNING:** This magic command is **experimental**, + > is not supported, and may be removed from future versions without notice. + + This magic command allows accessing or modifying the noise model used by + the `%experimental.simulate_noise` magic command. + ".Dedent(), Examples = new string[] { + @" + Return the currently set noise model: + ``` + In []: %experimental.noise_model + ``` + ".Dedent(), + @" + Set the noise model to a noise model given as JSON: + ``` + In []: %experimental.noise_model { ... } + ``` + ".Dedent(), + @" + Save the current noise model to a JSON file named + `noise-model.json`: + ``` + In []: %experimental.noise_model --save noise-model.json + ``` + ".Dedent(), + @" + Load the noise model stored in `noise-model.json`, + making it the active noise model: + ``` + In []: %experimental.noise_model --load noise-model.json + ``` + ".Dedent() } }) { diff --git a/src/Kernel/Magic/SimulateNoise.cs b/src/Kernel/Magic/SimulateNoise.cs index 90f8cbfc43..c678700465 100644 --- a/src/Kernel/Magic/SimulateNoise.cs +++ b/src/Kernel/Magic/SimulateNoise.cs @@ -31,10 +31,41 @@ public SimulateNoiseMagic(ISymbolResolver resolver, IConfigurationSource configu "experimental.simulate_noise", new Microsoft.Jupyter.Core.Documentation { - Summary = "TODO", - Description = "TODO", + Summary = "Runs a given function or operation on the OpenSystemsSimulator target machine.", + Description = @" + > **⚠ WARNING:** This magic command is **experimental**, + > is not supported, and may be removed from future versions without notice. + + This magic command allows executing a given function or operation + on the OpenSystemsSimulator target, simulating how that function or operation + will perform when run on noisy quantum hardware. + + #### See also + + - [`%experimental.noise_model`](https://docs.microsoft.com/qsharp/api/iqsharp-magic/experimental.noise_model) + + #### Required parameters + + - Q# operation or function name. This must be the first parameter, and must be a valid Q# operation + or function name that has been defined either in the notebook or in a Q# file in the same folder. + - Arguments for the Q# operation or function must also be specified as `key=value` pairs. + ".Dedent(), Examples = new string[] { + @" + Simulate a Q# operation defined as `operation MyOperation() : Result`: + ``` + In []: %simulate MyOperation + Out[]: + ``` + ".Dedent(), + @" + Simulate a Q# operation defined as `operation MyOperation(a : Int, b : Int) : Result`: + ``` + In []: %simulate MyOperation a=5 b=10 + Out[]: + ``` + ".Dedent(), } }) { @@ -75,6 +106,8 @@ public async Task RunAsync(string input, IChannel channel) var qsim = new OpenSystemsSimulator(); if (NoiseModelSource.NoiseModel != null) { + var json = JsonSerializer.Serialize(NoiseModelSource.NoiseModel); + Console.WriteLine(json); qsim.NoiseModel = NoiseModelSource.NoiseModel; } Logger?.LogDebug("Simulating with noise model: {NoiseModel}", JsonSerializer.Serialize(NoiseModelSource.NoiseModel)); diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index deccaa0b18..133ad30633 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index deccaa0b18..133ad30633 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index c423ea766b..e5d34ad799 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 659dd51a9b..1e4dd40621 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index 7abaffd38c..c7e6f5a07e 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + From 4abef448a929e369516edf1471a98c4721058aa8 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 12 Feb 2021 16:10:58 -0800 Subject: [PATCH 05/43] Add simulate_noise to qsharp-core. --- .../qsharp-core/qsharp/clients/iqsharp.py | 20 ++- src/Python/qsharp-core/qsharp/experimental.py | 163 ++++++++++++++++++ 2 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 src/Python/qsharp-core/qsharp/experimental.py diff --git a/src/Python/qsharp-core/qsharp/clients/iqsharp.py b/src/Python/qsharp-core/qsharp/clients/iqsharp.py index efb25ded0f..5d256acb82 100644 --- a/src/Python/qsharp-core/qsharp/clients/iqsharp.py +++ b/src/Python/qsharp-core/qsharp/clients/iqsharp.py @@ -3,7 +3,7 @@ ## # iqsharp.py: Client for the IQ# Jupyter kernel. ## -# Copyright (c) Microsoft Corporation. All rights reserved. +# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. ## @@ -193,6 +193,24 @@ def capture(msg): self._execute("%version", output_hook=capture, _quiet_=True, **kwargs) return versions + ## Experimental Methods ## + # These methods expose experimental functionality that may be removed without + # warning. To communicate to users that these are not reliable, we mark + # these methods as private, and will re-export them in the + # qsharp.experimental submodule. + + def _simulate_noise(self, op, **kwargs) -> Any: + return self._execute_callable_magic('experimental.simulate_noise', op, **kwargs) + + def _get_noise_model(self) -> str: + return self._execute('%experimental.noise_model') + + def _set_noise_model(self, op, json_data : str) -> None: + # We assume json_data is already serialized, so that we skip the support + # provided by _execute_magic and call directly. + return self._execute(f'%experimental.noise_model {json_data}') + + ## Internal-Use Methods ## def _execute_magic(self, magic : str, raise_on_stderr : bool = False, _quiet_ : bool = False, **kwargs) -> Any: diff --git a/src/Python/qsharp-core/qsharp/experimental.py b/src/Python/qsharp-core/qsharp/experimental.py new file mode 100644 index 0000000000..d93670742c --- /dev/null +++ b/src/Python/qsharp-core/qsharp/experimental.py @@ -0,0 +1,163 @@ +#!/bin/env python +# -*- coding: utf-8 -*- +## +# iqsharp.py: Client for the IQ# Jupyter kernel. +## +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +## + +## DESIGN NOTES ## + +# The functions in this module may take dependencies on QuTiP and NumPy, +# while neither of those are dependencies of the qsharp package on the whole. +# To avoid those becoming hard dependencies, we do not import either package +# at the top of this module, but do so inside each function that uses those +# dependencies. +# +# This has some performance and code maintenance implications, but allows for +# being permissive with respect to dependencies. + +## IMPORTS ## + +from qsharp.loader import QSharpCallable + +## EXPORTS ## + +__all__ = [ + "enable_noisy_simulation", + "get_noise_model", + "set_noise_model" +] + +## FUNCTIONS ## + +def enable_noisy_simulation(): + def simulate_noise(self, **kwargs): + return qsharp.client._simulate_noise(self, **kwargs) + QSharpCallable.simulate_noise = simulate_noise + +def is_rust_style_array(json_obj): + return ( + isinstance(json_obj, dict) and + 'v' in json_obj and + 'data' in json_obj and + 'dim' in json_obj and + json_obj['v'] == 1 + ) + +def rust_style_array_as_array(json_obj): + import numpy as np + arr = np.array(json_obj['data']).reshape(json_obj['dim'] + [2]).astype(complex) + return arr[..., 0] + 1j * arr[..., 1] + +def convert_to_arrays(json_obj): + return ( + # Add on a trailing index of length 2. + rust_style_array_as_array(json_obj) + if is_rust_style_array(json_obj) else + { + key: + convert_to_arrays(value) + if isinstance(value, dict) else + + [convert_to_arrays(element) for element in value] + if isinstance(value, list) else + + value + for key, value in json_obj.items() + } + ) + +def arr_to_qobj(arr): + import qutip as qt + import numpy as np + return qt.Qobj(arr, dims=[[2] * int(np.log2(arr.shape[1]))] * 2) + +def convert_to_qobjs(json_obj): + import qutip as qt + return ( + arr_to_qobj(json_obj['data']['Mixed']) + if 'data' in json_obj and 'Mixed' in json_obj['data'] else + + arr_to_qobj(json_obj['data']['Unitary']) + if 'data' in json_obj and 'Unitary' in json_obj['data'] else + + qt.kraus_to_super([arr_to_qobj(op) for op in json_obj['data']['KrausDecomposition']]) + if 'data' in json_obj and 'KrausDecomposition' in json_obj['data'] else + + { + key: + # Recurse if needed... + convert_to_qobjs(value) + if isinstance(value, dict) else + + [convert_to_qobjs(element) for element in value] + if isinstance(value, list) else + + # Just return value if there's nothing else to do. + value + for key, value in json_obj.items() + } + ) + +def arr_to_rust_style(arr): + import numpy as np + return { + 'v': 1, + 'dim': list(arr.shape), + 'data': np.moveaxis(np.array([arr.real, arr.imag]), 0, -1).reshape((-1, 2)).tolist() + } + +def qobj_to_rust_style(qobj, expect_state=False): + import qutip as qt + import numpy as np + data = None + n_qubits = 1 + # Figure out what kind of qobj we have and convert accordingly. + if qobj.type == 'oper': + n_qubits = len(qobj.dims[0]) + data = { + 'Mixed' if expect_state else 'Unitary': + arr_to_rust_style(qobj.data.todense()) + } + elif qobj.type == 'super': + n_qubits = len(qobj.dims[0][0]) + data = { + 'KrausDecomposition': arr_to_rust_style( + np.array([ + op.data.todense() + for op in qt.to_kraus(qobj) + ]) + ) + } + return { + "n_qubits": n_qubits, + "data": data + } + +def convert_to_rust_style(json_obj, expect_state=False): + import qutip as qt + return ( + qobj_to_rust_style(json_obj, expect_state=expect_state) + if isinstance(json_obj, qt.Qobj) else + + list(map(convert_to_rust_style, json_obj)) + if isinstance(json_obj, list) else + + { + key: convert_to_rust_style(value, expect_state=key == 'initial_state') + for key, value in json_obj.items() + } + if isinstance(json_obj, dict) else + + json_obj + ) + +def get_noise_model(): + noise_model = convert_to_arrays(qsharp.client._get_noise_model()) + # Convert {"Mixed": ...} and so forth to qobj. + return convert_to_qobjs(noise_model) + +def set_noise_model(noise_model): + qsharp.client._set_noise_model(json.dumps(convert_to_rust_style(noise_model)) From 759011114f81e1d17401110f5d9faed912d3761e Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Sat, 13 Feb 2021 10:10:07 -0800 Subject: [PATCH 06/43] Bump version and fix some syntax errors. --- src/AzureClient/AzureClient.csproj | 2 +- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- src/Python/qsharp-core/qsharp/experimental.py | 3 +- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/appsettings.json | 32 +++++++++---------- 10 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/AzureClient/AzureClient.csproj b/src/AzureClient/AzureClient.csproj index 7cc7e2843b..34fe16f0cd 100644 --- a/src/AzureClient/AzureClient.csproj +++ b/src/AzureClient/AzureClient.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 8bdbadc565..013bbc2e30 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index 355c521715..294b30bfa9 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index 133ad30633..292ce89bbc 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index 133ad30633..292ce89bbc 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Python/qsharp-core/qsharp/experimental.py b/src/Python/qsharp-core/qsharp/experimental.py index d93670742c..a5f05c2fd6 100644 --- a/src/Python/qsharp-core/qsharp/experimental.py +++ b/src/Python/qsharp-core/qsharp/experimental.py @@ -20,6 +20,7 @@ ## IMPORTS ## +import qsharp from qsharp.loader import QSharpCallable ## EXPORTS ## @@ -160,4 +161,4 @@ def get_noise_model(): return convert_to_qobjs(noise_model) def set_noise_model(noise_model): - qsharp.client._set_noise_model(json.dumps(convert_to_rust_style(noise_model)) + qsharp.client._set_noise_model(json.dumps(convert_to_rust_style(noise_model))) diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index e5d34ad799..505c19269b 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 1e4dd40621..2829a7741a 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index c7e6f5a07e..1ab2896081 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 6d2587340e..6d2bcc431c 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.15.210223161-alpha", + "Microsoft.Quantum.Compiler::0.15.210223344-alpha", - "Microsoft.Quantum.CsharpGeneration::0.15.210223161-alpha", - "Microsoft.Quantum.Development.Kit::0.15.210223161-alpha", - "Microsoft.Quantum.Simulators::0.15.210223161-alpha", - "Microsoft.Quantum.Xunit::0.15.210223161-alpha", + "Microsoft.Quantum.CsharpGeneration::0.15.210223344-alpha", + "Microsoft.Quantum.Development.Kit::0.15.210223344-alpha", + "Microsoft.Quantum.Simulators::0.15.210223344-alpha", + "Microsoft.Quantum.Xunit::0.15.210223344-alpha", - "Microsoft.Quantum.Standard::0.15.210223161-alpha", - "Microsoft.Quantum.Standard.Visualization::0.15.210223161-alpha", - "Microsoft.Quantum.Chemistry::0.15.210223161-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.15.210223161-alpha", - "Microsoft.Quantum.MachineLearning::0.15.210223161-alpha", - "Microsoft.Quantum.Numerics::0.15.210223161-alpha", + "Microsoft.Quantum.Standard::0.15.210223344-alpha", + "Microsoft.Quantum.Standard.Visualization::0.15.210223344-alpha", + "Microsoft.Quantum.Chemistry::0.15.210223344-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.15.210223344-alpha", + "Microsoft.Quantum.MachineLearning::0.15.210223344-alpha", + "Microsoft.Quantum.Numerics::0.15.210223344-alpha", - "Microsoft.Quantum.Katas::0.15.210223161-alpha", + "Microsoft.Quantum.Katas::0.15.210223344-alpha", - "Microsoft.Quantum.Research::0.15.210223161-alpha", + "Microsoft.Quantum.Research::0.15.210223344-alpha", - "Microsoft.Quantum.Providers.IonQ::0.15.210223161-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.15.210223161-alpha", - "Microsoft.Quantum.Providers.QCI::0.15.210223161-alpha" + "Microsoft.Quantum.Providers.IonQ::0.15.210223344-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.15.210223344-alpha", + "Microsoft.Quantum.Providers.QCI::0.15.210223344-alpha" ] } From f09e92c19989f143abafd0d815e00faa45be8136 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 17 Feb 2021 22:20:12 -0800 Subject: [PATCH 07/43] Add to noise model encoder. --- .../Visualization/OpenSystemsEncoders.cs | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs index b1ce291a52..6ad87ad398 100644 --- a/src/Jupyter/Visualization/OpenSystemsEncoders.cs +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -8,6 +8,7 @@ using System.Text.Json; using Microsoft.Jupyter.Core; using Microsoft.Quantum.IQSharp.Jupyter; +using System.Collections.Generic; namespace Microsoft.Quantum.Experimental { @@ -17,6 +18,7 @@ public class MixedStateToHtmlDisplayEncoder : IResultEncoder /// public string MimeType => MimeTypes.Html; + /// public EncodedData? Encode(object displayable) { if (displayable is MixedState state) @@ -54,8 +56,23 @@ public class NoiseModelToHtmlDisplayEncoder : IResultEncoder /// public string MimeType => MimeTypes.Html; + /// public EncodedData? Encode(object displayable) { + string RowForChannel(string name, Channel? channel) => + $@" + + {name} + + $$ + \left( \begin{{matrix}} + {channel?.Data?.AsLaTeXMatrixOfComplex() ?? ""} + \end{{matrix}} \right) + $$ + + + "; + if (displayable is NoiseModel noiseModel) { return $@" @@ -65,9 +82,41 @@ public class NoiseModelToHtmlDisplayEncoder : IResultEncoder Initial state $$ - \left( \begin{{matrix}} - {(noiseModel.InitialState as MixedState)?.Data?.AsLaTeXMatrixOfComplex() ?? ""} - \end{{matrix}} \right) + \left( \begin{{matrix}} + {(noiseModel.InitialState as MixedState)?.Data?.AsLaTeXMatrixOfComplex() ?? ""} + \end{{matrix}} \right) + $$ + + + {RowForChannel("CNOT", noiseModel?.Cnot)} + {RowForChannel("$I$", noiseModel?.I)} + {RowForChannel("$X$", noiseModel?.X)} + {RowForChannel("$Y$", noiseModel?.Y)} + {RowForChannel("$Z$", noiseModel?.Z)} + {RowForChannel("$H$", noiseModel?.H)} + {RowForChannel("$S$", noiseModel?.S)} + {RowForChannel("$S^{\\dagger}$", noiseModel?.SAdj)} + {RowForChannel("$T$", noiseModel?.T)} + {RowForChannel("$T^{\\dagger}$", noiseModel?.TAdj)} + + $Z$-measurement effects + + $$ + \left\{{ + { + string.Join(", ", + (noiseModel?.ZMeas?.Effects ?? new List()) + .Select( + channel => $@" + \left( \begin{{matrix}} + {channel?.Data?.AsLaTeXMatrixOfComplex() ?? ""} + \end{{matrix}} \right) + " + ) + ) + } + \right\}} + $$ From b3cd5ff3b6e160815ae5222543638c6057eced93 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 17 Feb 2021 23:44:50 -0800 Subject: [PATCH 08/43] Support setting opensim capacity through %config. --- src/Jupyter/ConfigurationSource/IConfigurationSource.cs | 7 +++++++ src/Kernel/Magic/SimulateNoise.cs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Jupyter/ConfigurationSource/IConfigurationSource.cs b/src/Jupyter/ConfigurationSource/IConfigurationSource.cs index 63455bb2db..7e2a08d5cb 100644 --- a/src/Jupyter/ConfigurationSource/IConfigurationSource.cs +++ b/src/Jupyter/ConfigurationSource/IConfigurationSource.cs @@ -129,5 +129,12 @@ public T GetOptionOrDefault(string optionName, T defaultValue) => /// public TraceVisualizationStyle TraceVisualizationStyle => GetOptionOrDefault("trace.style", TraceVisualizationStyle.Default); + + /// + /// Specifies the number of qubits that the open systems simulator + /// supports for use in running Q# programs. + /// + public uint OpenSystemsSimulatorCapacity => + GetOptionOrDefault("opensim.nQubits", 3); } } diff --git a/src/Kernel/Magic/SimulateNoise.cs b/src/Kernel/Magic/SimulateNoise.cs index c678700465..56290d29b6 100644 --- a/src/Kernel/Magic/SimulateNoise.cs +++ b/src/Kernel/Magic/SimulateNoise.cs @@ -103,7 +103,7 @@ public async Task RunAsync(string input, IChannel channel) var symbol = SymbolResolver.Resolve(name) as dynamic; // FIXME: Should be IQSharpSymbol. if (symbol == null) throw new InvalidOperationException($"Invalid operation name: {name}"); - var qsim = new OpenSystemsSimulator(); + var qsim = new OpenSystemsSimulator(ConfigurationSource.OpenSystemsSimulatorCapacity); if (NoiseModelSource.NoiseModel != null) { var json = JsonSerializer.Serialize(NoiseModelSource.NoiseModel); From 77206c9709affed132d74c8086c59efb163d6cfa Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 18 Feb 2021 13:57:21 -0800 Subject: [PATCH 09/43] Started adding integration tests for experimental opensim. --- src/Tests/IQsharpEngineTests.cs | 67 +++++++++++++++++++++++++++++++++ src/Tests/SNIPPETS.cs | 9 +++++ 2 files changed, 76 insertions(+) diff --git a/src/Tests/IQsharpEngineTests.cs b/src/Tests/IQsharpEngineTests.cs index b234637885..07eae5ae7a 100644 --- a/src/Tests/IQsharpEngineTests.cs +++ b/src/Tests/IQsharpEngineTests.cs @@ -17,6 +17,7 @@ using Microsoft.Quantum.IQSharp.ExecutionPathTracer; using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json; +using Microsoft.Quantum.Experimental; #pragma warning disable VSTHRD200 // Use "Async" suffix for async methods @@ -86,6 +87,31 @@ public static string SessionAsString(IEnumerable session) => return response.Output?.ToString(); } + public static async Task AssertNoisySimulate(IQSharpEngine engine, string snippetName, NoiseModel? noiseModel, params string[] messages) + { + await engine.Initialized; + var configSource = new ConfigurationSource(skipLoading: true); + var noiseModelSource = new NoiseModelSource(); + if (noiseModel != null) + { + noiseModelSource.NoiseModel = noiseModel; + } + + var simMagic = new SimulateNoiseMagic( + resolver: engine.SymbolsResolver!, + configurationSource: configSource, + logger: new UnitTestLogger(), + noiseModelSource: noiseModelSource + ); + var channel = new MockChannel(); + var response = await simMagic.Execute(snippetName, channel); + PrintResult(response, channel); + Assert.AreEqual(ExecuteStatus.Ok, response.Status); + CollectionAssert.AreEqual(messages.Select(ChannelWithNewLines.Format).ToArray(), channel.msgs.ToArray()); + + return response.Output?.ToString(); + } + public static async Task AssertEstimate(IQSharpEngine engine, string snippetName, params string[] messages) { await engine.Initialized; @@ -245,6 +271,47 @@ public async Task Estimate() await AssertEstimate(engine, "HelloQ"); } + [TestMethod] + public async Task NoisySimulateWithTwoQubitOperation() + { + var engine = await Init(); + var channel = new MockChannel(); + + // Compile it: + await AssertCompile(engine, SNIPPETS.HelloQ, "SimpleDebugOperation"); + + // Try running again: + // Note that noiseModel: null sets the noise model to be ideal. + await AssertNoisySimulate(engine, "SimpleDebugOperation", noiseModel: null); + } + + [TestMethod] + public async Task NoisySimulateWithFailIfOne() + { + var engine = await Init(); + var channel = new MockChannel(); + + // Compile it: + await AssertCompile(engine, SNIPPETS.HelloQ, "FailIfOne"); + + // Try running again: + // Note that noiseModel: null sets the noise model to be ideal. + await AssertNoisySimulate(engine, "FailIfOne", noiseModel: null); + } + + [TestMethod] + public async Task NoisySimulateWithTrivialOperation() + { + var engine = await Init(); + var channel = new MockChannel(); + + // Compile it: + await AssertCompile(engine, SNIPPETS.HelloQ, "HelloQ"); + + // Try running again: + await AssertNoisySimulate(engine, "HelloQ", noiseModel: null); + } + [TestMethod] public async Task Toffoli() { diff --git a/src/Tests/SNIPPETS.cs b/src/Tests/SNIPPETS.cs index e2e09d3689..1c7254c315 100644 --- a/src/Tests/SNIPPETS.cs +++ b/src/Tests/SNIPPETS.cs @@ -158,6 +158,15 @@ operation SimpleDebugOperation() : (Result, Result) } "; + public static string FailIfOne = + @" + operation FailIfOne() : Unit { + use q = Qubit(); + if M(q) == One { + fail ""Expected measuring a freshly allocated qubit to return Zero, but returned One.""; + } + } +"; public static string ApplyWithinBlock = @" /// # Summary From 6ea4ee133f605e8c35d3542a511640b13b42ce2e Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 18 Feb 2021 18:06:21 -0800 Subject: [PATCH 10/43] Fixed tests. --- src/Tests/IQsharpEngineTests.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Tests/IQsharpEngineTests.cs b/src/Tests/IQsharpEngineTests.cs index 07eae5ae7a..6309a891b6 100644 --- a/src/Tests/IQsharpEngineTests.cs +++ b/src/Tests/IQsharpEngineTests.cs @@ -272,13 +272,14 @@ public async Task Estimate() } [TestMethod] + [TestCategory("Experimental")] public async Task NoisySimulateWithTwoQubitOperation() { var engine = await Init(); var channel = new MockChannel(); // Compile it: - await AssertCompile(engine, SNIPPETS.HelloQ, "SimpleDebugOperation"); + await AssertCompile(engine, SNIPPETS.SimpleDebugOperation, "SimpleDebugOperation"); // Try running again: // Note that noiseModel: null sets the noise model to be ideal. @@ -286,13 +287,14 @@ public async Task NoisySimulateWithTwoQubitOperation() } [TestMethod] + [TestCategory("Experimental")] public async Task NoisySimulateWithFailIfOne() { var engine = await Init(); var channel = new MockChannel(); // Compile it: - await AssertCompile(engine, SNIPPETS.HelloQ, "FailIfOne"); + await AssertCompile(engine, SNIPPETS.FailIfOne, "FailIfOne"); // Try running again: // Note that noiseModel: null sets the noise model to be ideal. @@ -300,6 +302,7 @@ public async Task NoisySimulateWithFailIfOne() } [TestMethod] + [TestCategory("Experimental")] public async Task NoisySimulateWithTrivialOperation() { var engine = await Init(); @@ -309,7 +312,7 @@ public async Task NoisySimulateWithTrivialOperation() await AssertCompile(engine, SNIPPETS.HelloQ, "HelloQ"); // Try running again: - await AssertNoisySimulate(engine, "HelloQ", noiseModel: null); + await AssertNoisySimulate(engine, "HelloQ", noiseModel: null, "Hello from quantum world!"); } [TestMethod] From 2f4996d3d97c8a78561c6498fefa68a9bf0c718b Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 19 Feb 2021 08:33:56 -0800 Subject: [PATCH 11/43] Bump version and register display encoders. --- src/AzureClient/AzureClient.csproj | 2 +- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- src/Kernel/Magic/NoiseModel.cs | 7 +++- src/Kernel/Magic/SimulateNoise.cs | 8 ++++- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- src/Tests/IQsharpEngineTests.cs | 1 + .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/appsettings.json | 32 +++++++++---------- 12 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/AzureClient/AzureClient.csproj b/src/AzureClient/AzureClient.csproj index 34fe16f0cd..6703b4ec2a 100644 --- a/src/AzureClient/AzureClient.csproj +++ b/src/AzureClient/AzureClient.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 013bbc2e30..8b628b70d1 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index 294b30bfa9..37904d6ccf 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/Kernel/Magic/NoiseModel.cs b/src/Kernel/Magic/NoiseModel.cs index b8bbb18563..c108505a95 100644 --- a/src/Kernel/Magic/NoiseModel.cs +++ b/src/Kernel/Magic/NoiseModel.cs @@ -14,6 +14,7 @@ using Microsoft.Quantum.Simulation.Simulators; using System.Text.Json; using Microsoft.Extensions.Logging; +using Microsoft.Quantum.IQSharp.Kernel; namespace Microsoft.Quantum.Experimental { @@ -25,7 +26,7 @@ public class NoiseModelMagic : AbstractMagic /// /// Allows for querying noise models and for loading new noise models. /// - public NoiseModelMagic(INoiseModelSource noiseModelSource, ILogger logger) : base( + public NoiseModelMagic(IExecutionEngine engine, INoiseModelSource noiseModelSource, ILogger logger) : base( "experimental.noise_model", new Microsoft.Jupyter.Core.Documentation { @@ -69,6 +70,10 @@ Save the current noise model to a JSON file named }) { this.NoiseModelSource = noiseModelSource; + if (engine is IQSharpEngine iQSharpEngine) + { + iQSharpEngine.RegisterDisplayEncoder(new NoiseModelToHtmlDisplayEncoder()); + } } /// diff --git a/src/Kernel/Magic/SimulateNoise.cs b/src/Kernel/Magic/SimulateNoise.cs index 56290d29b6..ab481abded 100644 --- a/src/Kernel/Magic/SimulateNoise.cs +++ b/src/Kernel/Magic/SimulateNoise.cs @@ -11,6 +11,7 @@ using Microsoft.Quantum.IQSharp; using Microsoft.Quantum.IQSharp.Common; using Microsoft.Quantum.IQSharp.Jupyter; +using Microsoft.Quantum.IQSharp.Kernel; using Microsoft.Quantum.Simulation.Core; using Microsoft.Quantum.Simulation.Simulators; @@ -27,7 +28,7 @@ public class SimulateNoiseMagic : AbstractMagic /// operations and functions, and a configuration source used to set /// configuration options. /// - public SimulateNoiseMagic(ISymbolResolver resolver, IConfigurationSource configurationSource, INoiseModelSource noiseModelSource, ILogger logger) : base( + public SimulateNoiseMagic(IExecutionEngine engine, ISymbolResolver resolver, IConfigurationSource configurationSource, INoiseModelSource noiseModelSource, ILogger logger) : base( "experimental.simulate_noise", new Microsoft.Jupyter.Core.Documentation { @@ -73,6 +74,11 @@ or function name that has been defined either in the notebook or in a Q# file in this.ConfigurationSource = configurationSource; this.Logger = logger; this.NoiseModelSource = noiseModelSource; + + if (engine is IQSharpEngine iQSharpEngine) + { + iQSharpEngine.RegisterDisplayEncoder(new MixedStateToHtmlDisplayEncoder()); + } } /// diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index 292ce89bbc..7e07e7ad36 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index 292ce89bbc..7e07e7ad36 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/IQsharpEngineTests.cs b/src/Tests/IQsharpEngineTests.cs index 6309a891b6..6dd9e8c8f9 100644 --- a/src/Tests/IQsharpEngineTests.cs +++ b/src/Tests/IQsharpEngineTests.cs @@ -98,6 +98,7 @@ public static string SessionAsString(IEnumerable session) => } var simMagic = new SimulateNoiseMagic( + engine, resolver: engine.SymbolsResolver!, configurationSource: configSource, logger: new UnitTestLogger(), diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index 505c19269b..77f10d196c 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 2829a7741a..2cb0a9652e 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index 1ab2896081..313e26b381 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 6d2bcc431c..08dfc584aa 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.15.210223344-alpha", + "Microsoft.Quantum.Compiler::0.15.210223491-alpha", - "Microsoft.Quantum.CsharpGeneration::0.15.210223344-alpha", - "Microsoft.Quantum.Development.Kit::0.15.210223344-alpha", - "Microsoft.Quantum.Simulators::0.15.210223344-alpha", - "Microsoft.Quantum.Xunit::0.15.210223344-alpha", + "Microsoft.Quantum.CsharpGeneration::0.15.210223491-alpha", + "Microsoft.Quantum.Development.Kit::0.15.210223491-alpha", + "Microsoft.Quantum.Simulators::0.15.210223491-alpha", + "Microsoft.Quantum.Xunit::0.15.210223491-alpha", - "Microsoft.Quantum.Standard::0.15.210223344-alpha", - "Microsoft.Quantum.Standard.Visualization::0.15.210223344-alpha", - "Microsoft.Quantum.Chemistry::0.15.210223344-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.15.210223344-alpha", - "Microsoft.Quantum.MachineLearning::0.15.210223344-alpha", - "Microsoft.Quantum.Numerics::0.15.210223344-alpha", + "Microsoft.Quantum.Standard::0.15.210223491-alpha", + "Microsoft.Quantum.Standard.Visualization::0.15.210223491-alpha", + "Microsoft.Quantum.Chemistry::0.15.210223491-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.15.210223491-alpha", + "Microsoft.Quantum.MachineLearning::0.15.210223491-alpha", + "Microsoft.Quantum.Numerics::0.15.210223491-alpha", - "Microsoft.Quantum.Katas::0.15.210223344-alpha", + "Microsoft.Quantum.Katas::0.15.210223491-alpha", - "Microsoft.Quantum.Research::0.15.210223344-alpha", + "Microsoft.Quantum.Research::0.15.210223491-alpha", - "Microsoft.Quantum.Providers.IonQ::0.15.210223344-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.15.210223344-alpha", - "Microsoft.Quantum.Providers.QCI::0.15.210223344-alpha" + "Microsoft.Quantum.Providers.IonQ::0.15.210223491-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.15.210223491-alpha", + "Microsoft.Quantum.Providers.QCI::0.15.210223491-alpha" ] } From 1fb0ad5cced07d8f87949cd89b6b84d67d651128 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 19 Feb 2021 09:05:07 -0800 Subject: [PATCH 12/43] Fix some display issues in noise model encoder. --- .../Visualization/OpenSystemsEncoders.cs | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs index 6ad87ad398..65a0f1757e 100644 --- a/src/Jupyter/Visualization/OpenSystemsEncoders.cs +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -64,11 +64,41 @@ string RowForChannel(string name, Channel? channel) => {name} - $$ - \left( \begin{{matrix}} - {channel?.Data?.AsLaTeXMatrixOfComplex() ?? ""} - \end{{matrix}} \right) - $$ + $${ + // NB: We use a switch expression here to + // pattern match on what representation + // the given channel is expressed in. + // In doing so, we use the {} pattern + // to capture non-null channel data, + // so that we are guaranteed that we + // only try to display channels that + // were successfully deserialized. + channel switch + { + UnitaryChannel { Data: {} data } => + $@" + \left( \begin{{matrix}} + {data.AsLaTeXMatrixOfComplex() ?? ""} + \end{{matrix}} \right)", + KrausDecompositionChannel { Data: {} data } => + $@" + \left\{{{ + string.Join(", ", + Enumerable + .Range(0, data.Shape[0]) + .Select(idxKrausOperator => + $@" + \left( \begin{{matrix}} + {data[idxKrausOperator].AsLaTeXMatrixOfComplex()} + \end{{matrix}} \right) + " + ) + ) + }\right\}} + ", + _ => "" + } + }$$ "; @@ -79,7 +109,7 @@ string RowForChannel(string name, Channel? channel) => - @@ -67,20 +67,21 @@ string RowForChannel(string name, Channel? channel) => $${ // NB: We use a switch expression here to // pattern match on what representation - // the given channel is expressed in. + // the given process is expressed in. // In doing so, we use the {} pattern - // to capture non-null channel data, + // to capture non-null process data, // so that we are guaranteed that we - // only try to display channels that + // only try to display processs that // were successfully deserialized. - channel switch + // TODO: Add other variants of process here. + process switch { - UnitaryChannel { Data: {} data } => + UnitaryProcess { Data: {} data } => $@" \left( \begin{{matrix}} {data.AsLaTeXMatrixOfComplex() ?? ""} \end{{matrix}} \right)", - KrausDecompositionChannel { Data: {} data } => + KrausDecompositionProcess { Data: {} data } => $@" \left\{{{ string.Join(", ", @@ -118,16 +119,16 @@ string RowForChannel(string name, Channel? channel) => $$ - {RowForChannel("CNOT", noiseModel?.Cnot)} - {RowForChannel("$I$", noiseModel?.I)} - {RowForChannel("$X$", noiseModel?.X)} - {RowForChannel("$Y$", noiseModel?.Y)} - {RowForChannel("$Z$", noiseModel?.Z)} - {RowForChannel("$H$", noiseModel?.H)} - {RowForChannel("$S$", noiseModel?.S)} - {RowForChannel("$S^{\\dagger}$", noiseModel?.SAdj)} - {RowForChannel("$T$", noiseModel?.T)} - {RowForChannel("$T^{\\dagger}$", noiseModel?.TAdj)} + {RowForProcess("CNOT", noiseModel?.Cnot)} + {RowForProcess("$I$", noiseModel?.I)} + {RowForProcess("$X$", noiseModel?.X)} + {RowForProcess("$Y$", noiseModel?.Y)} + {RowForProcess("$Z$", noiseModel?.Z)} + {RowForProcess("$H$", noiseModel?.H)} + {RowForProcess("$S$", noiseModel?.S)} + {RowForProcess("$S^{\\dagger}$", noiseModel?.SAdj)} + {RowForProcess("$T$", noiseModel?.T)} + {RowForProcess("$T^{\\dagger}$", noiseModel?.TAdj)} @@ -130,14 +145,14 @@ string RowForProcess(string name, Process? process) => {RowForProcess("$T$", noiseModel?.T)} {RowForProcess("$T^{\\dagger}$", noiseModel?.TAdj)} - - + + }\right\}}$$ + ", + ZMeasurementInstrument { PrReadoutError: var prReadoutError } => + $@"$Z$-basis measurement w/ error probability {prReadoutError}", + {} unknown => unknown.ToString(), + null => "" + } + }
Noise model
Initial state + Initial state $$ \left( \begin{{matrix}} From c13dc836951fb40fa0af6844efdb93eeae7cd70e Mon Sep 17 00:00:00 2001 From: Sarah Kaiser Date: Thu, 25 Feb 2021 14:42:04 -0800 Subject: [PATCH 13/43] fixing a bug in json noise model import (#412) --- src/Python/qsharp-core/qsharp/clients/iqsharp.py | 2 +- src/Python/qsharp-core/qsharp/experimental.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Python/qsharp-core/qsharp/clients/iqsharp.py b/src/Python/qsharp-core/qsharp/clients/iqsharp.py index 5d256acb82..f70947c0d8 100644 --- a/src/Python/qsharp-core/qsharp/clients/iqsharp.py +++ b/src/Python/qsharp-core/qsharp/clients/iqsharp.py @@ -205,7 +205,7 @@ def _simulate_noise(self, op, **kwargs) -> Any: def _get_noise_model(self) -> str: return self._execute('%experimental.noise_model') - def _set_noise_model(self, op, json_data : str) -> None: + def _set_noise_model(self, json_data : str) -> None: # We assume json_data is already serialized, so that we skip the support # provided by _execute_magic and call directly. return self._execute(f'%experimental.noise_model {json_data}') diff --git a/src/Python/qsharp-core/qsharp/experimental.py b/src/Python/qsharp-core/qsharp/experimental.py index a5f05c2fd6..c5f04db55b 100644 --- a/src/Python/qsharp-core/qsharp/experimental.py +++ b/src/Python/qsharp-core/qsharp/experimental.py @@ -22,6 +22,7 @@ import qsharp from qsharp.loader import QSharpCallable +import json ## EXPORTS ## From 75e4a3b3cf3eb367243f0827b46dc58f635d4962 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 18 Mar 2021 09:09:05 -0700 Subject: [PATCH 14/43] Update to 0.15.210324351-alpha. --- src/AzureClient/AzureClient.csproj | 2 +- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/appsettings.json | 32 +++++++++---------- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/AzureClient/AzureClient.csproj b/src/AzureClient/AzureClient.csproj index 6703b4ec2a..29c655708b 100644 --- a/src/AzureClient/AzureClient.csproj +++ b/src/AzureClient/AzureClient.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 8b628b70d1..6b491ec8da 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index 37904d6ccf..8060ff68b8 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index 7e07e7ad36..3c7abb23f4 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index 7e07e7ad36..3c7abb23f4 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index 77f10d196c..8949697525 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 2cb0a9652e..a8cc66feae 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index 313e26b381..cad9cedb5e 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 08dfc584aa..0f3614d27b 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.15.210223491-alpha", + "Microsoft.Quantum.Compiler::0.15.210324351-alpha", - "Microsoft.Quantum.CsharpGeneration::0.15.210223491-alpha", - "Microsoft.Quantum.Development.Kit::0.15.210223491-alpha", - "Microsoft.Quantum.Simulators::0.15.210223491-alpha", - "Microsoft.Quantum.Xunit::0.15.210223491-alpha", + "Microsoft.Quantum.CsharpGeneration::0.15.210324351-alpha", + "Microsoft.Quantum.Development.Kit::0.15.210324351-alpha", + "Microsoft.Quantum.Simulators::0.15.210324351-alpha", + "Microsoft.Quantum.Xunit::0.15.210324351-alpha", - "Microsoft.Quantum.Standard::0.15.210223491-alpha", - "Microsoft.Quantum.Standard.Visualization::0.15.210223491-alpha", - "Microsoft.Quantum.Chemistry::0.15.210223491-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.15.210223491-alpha", - "Microsoft.Quantum.MachineLearning::0.15.210223491-alpha", - "Microsoft.Quantum.Numerics::0.15.210223491-alpha", + "Microsoft.Quantum.Standard::0.15.210324351-alpha", + "Microsoft.Quantum.Standard.Visualization::0.15.210324351-alpha", + "Microsoft.Quantum.Chemistry::0.15.210324351-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.15.210324351-alpha", + "Microsoft.Quantum.MachineLearning::0.15.210324351-alpha", + "Microsoft.Quantum.Numerics::0.15.210324351-alpha", - "Microsoft.Quantum.Katas::0.15.210223491-alpha", + "Microsoft.Quantum.Katas::0.15.210324351-alpha", - "Microsoft.Quantum.Research::0.15.210223491-alpha", + "Microsoft.Quantum.Research::0.15.210324351-alpha", - "Microsoft.Quantum.Providers.IonQ::0.15.210223491-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.15.210223491-alpha", - "Microsoft.Quantum.Providers.QCI::0.15.210223491-alpha" + "Microsoft.Quantum.Providers.IonQ::0.15.210324351-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.15.210324351-alpha", + "Microsoft.Quantum.Providers.QCI::0.15.210324351-alpha" ] } From 39b9ebcbb24ad935362840a700aa286b064b8232 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 23 Mar 2021 15:34:11 -0700 Subject: [PATCH 15/43] Update to 0.15.210324357-alpha. --- src/AzureClient/AzureClient.csproj | 2 +- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/appsettings.json | 32 +++++++++---------- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/AzureClient/AzureClient.csproj b/src/AzureClient/AzureClient.csproj index 29c655708b..abfa47fa2d 100644 --- a/src/AzureClient/AzureClient.csproj +++ b/src/AzureClient/AzureClient.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 6b491ec8da..bb56ea386e 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index 8060ff68b8..bc75b18122 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index 3c7abb23f4..948fc33df8 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index 3c7abb23f4..948fc33df8 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index 8949697525..c574fe515b 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index a8cc66feae..f1dd97dc8a 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index cad9cedb5e..4748f4347a 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 0f3614d27b..e5506f10fa 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.15.210324351-alpha", + "Microsoft.Quantum.Compiler::0.15.210324357-alpha", - "Microsoft.Quantum.CsharpGeneration::0.15.210324351-alpha", - "Microsoft.Quantum.Development.Kit::0.15.210324351-alpha", - "Microsoft.Quantum.Simulators::0.15.210324351-alpha", - "Microsoft.Quantum.Xunit::0.15.210324351-alpha", + "Microsoft.Quantum.CsharpGeneration::0.15.210324357-alpha", + "Microsoft.Quantum.Development.Kit::0.15.210324357-alpha", + "Microsoft.Quantum.Simulators::0.15.210324357-alpha", + "Microsoft.Quantum.Xunit::0.15.210324357-alpha", - "Microsoft.Quantum.Standard::0.15.210324351-alpha", - "Microsoft.Quantum.Standard.Visualization::0.15.210324351-alpha", - "Microsoft.Quantum.Chemistry::0.15.210324351-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.15.210324351-alpha", - "Microsoft.Quantum.MachineLearning::0.15.210324351-alpha", - "Microsoft.Quantum.Numerics::0.15.210324351-alpha", + "Microsoft.Quantum.Standard::0.15.210324357-alpha", + "Microsoft.Quantum.Standard.Visualization::0.15.210324357-alpha", + "Microsoft.Quantum.Chemistry::0.15.210324357-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.15.210324357-alpha", + "Microsoft.Quantum.MachineLearning::0.15.210324357-alpha", + "Microsoft.Quantum.Numerics::0.15.210324357-alpha", - "Microsoft.Quantum.Katas::0.15.210324351-alpha", + "Microsoft.Quantum.Katas::0.15.210324357-alpha", - "Microsoft.Quantum.Research::0.15.210324351-alpha", + "Microsoft.Quantum.Research::0.15.210324357-alpha", - "Microsoft.Quantum.Providers.IonQ::0.15.210324351-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.15.210324351-alpha", - "Microsoft.Quantum.Providers.QCI::0.15.210324351-alpha" + "Microsoft.Quantum.Providers.IonQ::0.15.210324357-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.15.210324357-alpha", + "Microsoft.Quantum.Providers.QCI::0.15.210324357-alpha" ] } From 08d825b0e647c8f113cf55828ac43a6db797f197 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 3 Jun 2021 09:19:01 -0700 Subject: [PATCH 16/43] Capture more information in assertion logs. --- src/Tests/IQsharpEngineTests.cs | 40 +++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/Tests/IQsharpEngineTests.cs b/src/Tests/IQsharpEngineTests.cs index 6dd9e8c8f9..d0d4583e06 100644 --- a/src/Tests/IQsharpEngineTests.cs +++ b/src/Tests/IQsharpEngineTests.cs @@ -25,6 +25,12 @@ namespace Tests.IQSharp { + internal static class TestExtensions + { + internal static void AssertIsOk(this ExecutionResult response) => + Assert.AreEqual(ExecuteStatus.Ok, response.Status, $"Response was not marked as Ok.\n\tActual status: {response.Status}\n\tResponse output: {response.Output}"); + } + [TestClass] public class IQSharpEngineTests { @@ -107,7 +113,7 @@ public static string SessionAsString(IEnumerable session) => var channel = new MockChannel(); var response = await simMagic.Execute(snippetName, channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); CollectionAssert.AreEqual(messages.Select(ChannelWithNewLines.Format).ToArray(), channel.msgs.ToArray()); return response.Output?.ToString(); @@ -123,7 +129,7 @@ public static string SessionAsString(IEnumerable session) => var response = await estimateMagic.Execute(snippetName, channel); var result = response.Output as DataTable; PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); Assert.IsNotNull(result); Assert.AreEqual(9, result?.Rows.Count); var keys = result?.Rows.Cast().Select(row => row.ItemArray[0]).ToList(); @@ -151,16 +157,16 @@ private async Task AssertTrace(string name, ExecutionPath expectedPath, int expe // Add dependencies: var response = await pkgMagic.Execute("mock.standard", channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); // Reload workspace: response = await wsMagic.Execute("reload", channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); response = await traceMagic.Execute(name, channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); var message = channel.iopubMessages.ElementAtOrDefault(0); Assert.IsNotNull(message); @@ -331,7 +337,7 @@ public async Task Toffoli() var response = await toffoliMagic.Execute("HelloQ", channel); var result = response.Output as Dictionary; PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); Assert.AreEqual(1, channel.msgs.Count); Assert.AreEqual(ChannelWithNewLines.Format("Hello from quantum world!"), channel.msgs[0]); } @@ -422,7 +428,7 @@ public async Task ReportWarnings() var channel = new MockChannel(); var response = await engine.ExecuteMundane(SNIPPETS.ThreeWarnings, channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); Assert.AreEqual(3, channel.msgs.Count); Assert.AreEqual(0, channel.errors.Count); Assert.AreEqual("ThreeWarnings", @@ -434,7 +440,7 @@ public async Task ReportWarnings() var channel = new MockChannel(); var response = await engine.ExecuteMundane(SNIPPETS.OneWarning, channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); Assert.AreEqual(1, channel.msgs.Count); Assert.AreEqual(0, channel.errors.Count); Assert.AreEqual("OneWarning", @@ -470,7 +476,7 @@ public async Task TestPackages() var response = await pkgMagic.Execute("", channel); var result = response.Output as string[]; PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); Assert.AreEqual(0, channel.msgs.Count); Assert.AreEqual(packageCount, result?.Length); Assert.AreEqual("Microsoft.Quantum.Standard::0.0.0", result?[0]); @@ -485,7 +491,7 @@ public async Task TestPackages() response = await pkgMagic.Execute("mock.chemistry", channel); result = response.Output as string[]; PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); Assert.AreEqual(0, channel.msgs.Count); Assert.IsNotNull(result); Assert.AreEqual(packageCount + 1, result?.Length); @@ -522,7 +528,7 @@ public async Task TestProjectMagic() var channel = new MockChannel(); var response = await projectMagic.Execute("../Workspace.ProjectReferences/Workspace.ProjectReferences.csproj", channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); var loadedProjectFiles = response.Output as string[]; Assert.AreEqual(3, loadedProjectFiles?.Length); } @@ -541,7 +547,7 @@ public async Task TestWho() var response = await whoMagic.Execute("", channel); var result = response.Output as string[]; PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); Assert.AreEqual(6, result?.Length); Assert.AreEqual("HelloQ", result?[0]); Assert.AreEqual("Tests.qss.NoOp", result?[4]); @@ -578,20 +584,20 @@ public async Task TestWorkspace() // Add dependencies: response = await pkgMagic.Execute("mock.chemistry", channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); response = await pkgMagic.Execute("mock.research", channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); // Reload workspace: response = await wsMagic.Execute("reload", channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); response = await wsMagic.Execute("", channel); result = response.Output as string[]; PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); Assert.AreEqual(2, result?.Length); // Compilation must work: @@ -605,7 +611,7 @@ public async Task TestWorkspace() // Check that everything still works: response = await wsMagic.Execute("", channel); PrintResult(response, channel); - Assert.AreEqual(ExecuteStatus.Ok, response.Status); + response.AssertIsOk(); } [TestMethod] From 7ee07131b084b0769a5ea46b78d1d8be8f60cab5 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 3 Jun 2021 15:55:43 -0700 Subject: [PATCH 17/43] Adapt to changes in noise model serialization API. --- .../Visualization/OpenSystemsEncoders.cs | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs index 65a0f1757e..9ec5fdd467 100644 --- a/src/Jupyter/Visualization/OpenSystemsEncoders.cs +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -59,7 +59,7 @@ public class NoiseModelToHtmlDisplayEncoder : IResultEncoder /// public EncodedData? Encode(object displayable) { - string RowForChannel(string name, Channel? channel) => + string RowForProcess(string name, Process? process) => $@"
{name}
$Z$-measurement effects @@ -135,11 +136,12 @@ string RowForChannel(string name, Channel? channel) => \left\{{ { string.Join(", ", - (noiseModel?.ZMeas?.Effects ?? new List()) + // TODO: visualize other kinds of effects here. + ((noiseModel?.ZMeas as EffectsInstrument)?.Effects ?? new List()) .Select( - channel => $@" + process => $@" \left( \begin{{matrix}} - {channel?.Data?.AsLaTeXMatrixOfComplex() ?? ""} + {process?.Data?.AsLaTeXMatrixOfComplex() ?? ""} \end{{matrix}} \right) " ) From e572354a2a99dec00f0d6907ba340941cd984a1e Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Thu, 3 Jun 2021 16:58:34 -0700 Subject: [PATCH 18/43] One more fix to serialization support. --- src/Jupyter/Visualization/OpenSystemsEncoders.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs index 9ec5fdd467..3265710483 100644 --- a/src/Jupyter/Visualization/OpenSystemsEncoders.cs +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -141,7 +141,7 @@ string RowForProcess(string name, Process? process) => .Select( process => $@" \left( \begin{{matrix}} - {process?.Data?.AsLaTeXMatrixOfComplex() ?? ""} + {(process as ArrayProcess)?.Data?.AsLaTeXMatrixOfComplex() ?? ""} \end{{matrix}} \right) " ) From 3ab13428861a91014aec29dea469632d7db3f9ce Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 4 Jun 2021 08:40:57 -0700 Subject: [PATCH 19/43] Use alpha from https://github.com/microsoft/qsharp-runtime/pull/709. --- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/appsettings.json | 32 +++++++++---------- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 6140b5b4f0..734e6ef55f 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index 0fc4dc0346..33ce400d90 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index 027424de79..afe98d8a65 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index 027424de79..afe98d8a65 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index 766b532a17..c6d826fb0c 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 11d17ff86d..14ed83b406 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index 6bfe521283..fead303bdd 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 17643dcffc..9447ad4bc1 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.16.2105140472", + "Microsoft.Quantum.Compiler::0.17.210627536-alpha", - "Microsoft.Quantum.CSharpGeneration::0.16.2105140472", - "Microsoft.Quantum.Development.Kit::0.16.2105140472", - "Microsoft.Quantum.Simulators::0.16.2105140472", - "Microsoft.Quantum.Xunit::0.16.2105140472", + "Microsoft.Quantum.CSharpGeneration::0.17.210627536-alpha", + "Microsoft.Quantum.Development.Kit::0.17.210627536-alpha", + "Microsoft.Quantum.Simulators::0.17.210627536-alpha", + "Microsoft.Quantum.Xunit::0.17.210627536-alpha", - "Microsoft.Quantum.Standard::0.16.2105140472", - "Microsoft.Quantum.Standard.Visualization::0.16.2105140472", - "Microsoft.Quantum.Chemistry::0.16.2105140472", - "Microsoft.Quantum.Chemistry.Jupyter::0.16.2105140472", - "Microsoft.Quantum.MachineLearning::0.16.2105140472", - "Microsoft.Quantum.Numerics::0.16.2105140472", + "Microsoft.Quantum.Standard::0.17.210627536-alpha", + "Microsoft.Quantum.Standard.Visualization::0.17.210627536-alpha", + "Microsoft.Quantum.Chemistry::0.17.210627536-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627536-alpha", + "Microsoft.Quantum.MachineLearning::0.17.210627536-alpha", + "Microsoft.Quantum.Numerics::0.17.210627536-alpha", - "Microsoft.Quantum.Katas::0.16.2105140472", + "Microsoft.Quantum.Katas::0.17.210627536-alpha", - "Microsoft.Quantum.Research::0.16.2105140472", + "Microsoft.Quantum.Research::0.17.210627536-alpha", - "Microsoft.Quantum.Providers.IonQ::0.16.2105140472", - "Microsoft.Quantum.Providers.Honeywell::0.16.2105140472", - "Microsoft.Quantum.Providers.QCI::0.16.2105140472" + "Microsoft.Quantum.Providers.IonQ::0.17.210627536-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.17.210627536-alpha", + "Microsoft.Quantum.Providers.QCI::0.17.210627536-alpha" ] } From bb357cc9c51903b3d62d827fc4f1fec8ee8fa7fe Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 4 Jun 2021 09:20:28 -0700 Subject: [PATCH 20/43] Support more processes and instruments in display encoders. --- .../Visualization/OpenSystemsEncoders.cs | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs index 3265710483..a8974731fb 100644 --- a/src/Jupyter/Visualization/OpenSystemsEncoders.cs +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -97,7 +97,22 @@ string RowForProcess(string name, Process? process) => ) }\right\}} ", - _ => "" + MixedPauliProcess { Operators: {} ops } => + $@" + \text{{(mixed Pauli process) }} + \left\{{{ + string.Join(", ", + ops.Select( + item => $@"{item.Item1} {string.Join( + "", + item.Item2.Select(pauli => pauli.ToString()) + )}" + ) + ) + }\right\}} + ", + {} unknown => unknown.ToString(), + null => "" } }$$
$Z$-measurement effects - $$ - \left\{{ - { + $Z$-measurement{ + noiseModel?.ZMeas switch + { + EffectsInstrument { Effects: var effects } => $@" + $$\left\{{{ string.Join(", ", - // TODO: visualize other kinds of effects here. - ((noiseModel?.ZMeas as EffectsInstrument)?.Effects ?? new List()) + (effects ?? new List()) .Select( process => $@" \left( \begin{{matrix}} @@ -146,10 +161,14 @@ string RowForProcess(string name, Process? process) => " ) ) - } - \right\}} - $$ -
".ToEncodedData(); From f864f812aeee380e94ea79cbc07520cbd677954d Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 4 Jun 2021 09:52:08 -0700 Subject: [PATCH 21/43] Allow Python client to inform kernel about experimental features. --- src/Kernel/ExperimentalFeatures.cs | 65 +++++++++++++++++++ src/Python/qsharp-core/qsharp/experimental.py | 25 +++++++ src/Tool/Telemetry.cs | 17 ++++- 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/Kernel/ExperimentalFeatures.cs diff --git a/src/Kernel/ExperimentalFeatures.cs b/src/Kernel/ExperimentalFeatures.cs new file mode 100644 index 0000000000..b747c9e995 --- /dev/null +++ b/src/Kernel/ExperimentalFeatures.cs @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.Threading.Tasks; +using Microsoft.Quantum.IQSharp; +using Microsoft.Jupyter.Core; +using Microsoft.Jupyter.Core.Protocol; +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace Microsoft.Quantum.IQSharp.Kernel +{ + + /// + /// Message content to be received when a client asks for an + /// experimental feature to be turned on. + /// + public class ExperimentalFeatureContent : MessageContent + { + /// + /// The name of the experimental feature to be enabled. + /// + [JsonProperty("feature_name")] + public string? FeatureName { get; set; } + + /// + /// The names and versions of any optional packages used with the + /// requested experimental feature. + /// + [JsonProperty("optional_dependencies")] + public List? OptionalDependencies { get; set; } + } + + /// + /// Event type for when a Python client enables an experimental + /// feature. + /// + public class ExperimentalFeatureEnabledEvent : Event + { + } + + /// + /// Shell handler that allows for firing off events when a Python + /// client enables an experimental feature via + /// qsharp.experimental. + /// + internal class ExperimentalFeaturesShellHandler : IShellHandler + { + public string MessageType => "iqsharp_python_enable_experimental"; + private readonly IEventService events; + + public ExperimentalFeaturesShellHandler(IEventService events) + { + this.events = events; + } + + public Task HandleAsync(Message message) + { + var content = message.To(); + events?.Trigger(content); + return Task.CompletedTask; + } + } + +} \ No newline at end of file diff --git a/src/Python/qsharp-core/qsharp/experimental.py b/src/Python/qsharp-core/qsharp/experimental.py index c5f04db55b..e3f13fd217 100644 --- a/src/Python/qsharp-core/qsharp/experimental.py +++ b/src/Python/qsharp-core/qsharp/experimental.py @@ -35,6 +35,31 @@ ## FUNCTIONS ## def enable_noisy_simulation(): + # Try to import optional packages used by noise modelling. + optional_dependencies = [] + try: + import numpy as np + optional_dependencies.append(f"numpy:{np.__version__}") + except: + np = None + + try: + import qutip as qt + optional_dependencies.append(f"qutip:{qt.__version__}") + except: + qt = None + + # Tell the kernel to turn on experimental features. + try: + content = { + "feature_name": "noisy_simulation", + "optional_dependencies": optional_dependencies + } + msg = qsharp.client.kernel_client.session.msg('iqsharp_python_enable_experimental', content) + qsharp.client.kernel_client.shell_channel.send(msg) + except: + pass + def simulate_noise(self, **kwargs): return qsharp.client._simulate_noise(self, **kwargs) QSharpCallable.simulate_noise = simulate_noise diff --git a/src/Tool/Telemetry.cs b/src/Tool/Telemetry.cs index 6ff432eafa..6170cdb7e2 100644 --- a/src/Tool/Telemetry.cs +++ b/src/Tool/Telemetry.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #if TELEMETRY @@ -15,6 +15,7 @@ using Microsoft.Quantum.Simulation.Simulators; using static Microsoft.Jupyter.Core.BaseEngine; using Microsoft.Quantum.IQSharp.Kernel; +using System.Collections.Generic; namespace Microsoft.Quantum.IQSharp { @@ -50,6 +51,20 @@ public TelemetryService( LogManager.Teardown(); }; + eventService.Events().On += (content) => + { + var evt = "ExperimentalFeatureEnabled".AsTelemetryEvent(); + evt.SetProperty( + "FeatureName".WithTelemetryNamespace(), + content.FeatureName + ); + evt.SetProperty( + "OptionalDependencies".WithTelemetryNamespace(), + string.Join(",", content.OptionalDependencies ?? new List()) + ); + TelemetryLogger.LogEvent(evt); + }; + eventService.OnServiceInitialized().On += (metadataController) => metadataController.MetadataChanged += (metadataController, propertyChanged) => SetSharedContextIfChanged(metadataController, propertyChanged, From c15d77715b95cfb625695be7d5dab8d43a1036b4 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 4 Jun 2021 10:29:13 -0700 Subject: [PATCH 22/43] Allow clients to override kernel name used to communicate with IQ#. --- src/Python/qsharp-core/qsharp/clients/__init__.py | 5 ++++- src/Python/qsharp-core/qsharp/clients/iqsharp.py | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Python/qsharp-core/qsharp/clients/__init__.py b/src/Python/qsharp-core/qsharp/clients/__init__.py index 16557a1439..6d3130e563 100644 --- a/src/Python/qsharp-core/qsharp/clients/__init__.py +++ b/src/Python/qsharp-core/qsharp/clients/__init__.py @@ -27,8 +27,11 @@ def _start_client(): client_name = os.getenv("QSHARP_PY_CLIENT", "iqsharp") if client_name == "iqsharp": + # Allow users to override what kernel is used, making it easier to + # test kernels side-by-side. + kernel_name = os.getenv("QSHARP_PY_IQSHARP_KERNEL_NAME", "iqsharp") import qsharp.clients.iqsharp - client = qsharp.clients.iqsharp.IQSharpClient() + client = qsharp.clients.iqsharp.IQSharpClient(kernel_name=kernel_name) elif client_name == "mock": import qsharp.clients.mock client = qsharp.clients.mock.MockClient() diff --git a/src/Python/qsharp-core/qsharp/clients/iqsharp.py b/src/Python/qsharp-core/qsharp/clients/iqsharp.py index f70947c0d8..2e8aae4791 100644 --- a/src/Python/qsharp-core/qsharp/clients/iqsharp.py +++ b/src/Python/qsharp-core/qsharp/clients/iqsharp.py @@ -73,8 +73,13 @@ class IQSharpClient(object): kernel_client = None _busy : bool = False - def __init__(self): - self.kernel_manager = jupyter_client.KernelManager(kernel_name='iqsharp') +class IQSharpClient(object): + kernel_manager = None + kernel_client = None + _busy : bool = False + + def __init__(self, kernel_name: str = 'iqsharp'): + self.kernel_manager = jupyter_client.KernelManager(kernel_name=kernel_name) ## Server Lifecycle ## From 2102c2946beff51109f1339efd35fccd41426f8a Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 4 Jun 2021 10:41:47 -0700 Subject: [PATCH 23/43] Fix serialization bug. --- src/Kernel/CustomShell/MessageExtensions.cs | 14 +++++++++++++- src/Tool/Telemetry.cs | 6 +++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Kernel/CustomShell/MessageExtensions.cs b/src/Kernel/CustomShell/MessageExtensions.cs index 22341f3c67..3c926bcebc 100644 --- a/src/Kernel/CustomShell/MessageExtensions.cs +++ b/src/Kernel/CustomShell/MessageExtensions.cs @@ -3,6 +3,7 @@ using Microsoft.Jupyter.Core.Protocol; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Linq; @@ -29,9 +30,20 @@ public static T To(this Message message) { var jsonPropertyAttribute = property.GetCustomAttributes(true).OfType().FirstOrDefault(); var propertyName = jsonPropertyAttribute?.PropertyName ?? property.Name; + var propertyType = property.PropertyType; if (content.Data.TryGetValue(propertyName, out var value)) { - property.SetValue(result, content.Data[propertyName]); + var data = content.Data[propertyName]; + // If the unknown content's data is a JToken, that + // indicates that we need to further deserialize it. + if (data is JToken tokenData) + { + property.SetValue(result, tokenData.ToObject(propertyType)); + } + else + { + property.SetValue(result, data); + } } } return result; diff --git a/src/Tool/Telemetry.cs b/src/Tool/Telemetry.cs index 6170cdb7e2..4a1add898f 100644 --- a/src/Tool/Telemetry.cs +++ b/src/Tool/Telemetry.cs @@ -1,7 +1,7 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#if TELEMETRY +// #if TELEMETRY using System; using System.IO; @@ -249,4 +249,4 @@ public static EventProperties AsTelemetryEvent(this ExecutedEventArgs info) } -#endif +// #endif From 580eb0a07b882b5ee7e6791f658943da81a23e1d Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 4 Jun 2021 12:44:24 -0700 Subject: [PATCH 24/43] Allow loading noise models by name. --- .../NoiseModelSource/NoiseModelSource.cs | 6 +++++- src/Kernel/Magic/NoiseModel.cs | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Jupyter/NoiseModelSource/NoiseModelSource.cs b/src/Jupyter/NoiseModelSource/NoiseModelSource.cs index a30859252a..fecdc37476 100644 --- a/src/Jupyter/NoiseModelSource/NoiseModelSource.cs +++ b/src/Jupyter/NoiseModelSource/NoiseModelSource.cs @@ -3,6 +3,7 @@ #nullable enable +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -14,7 +15,10 @@ namespace Microsoft.Quantum.Experimental public class NoiseModelSource : INoiseModelSource { - public NoiseModel NoiseModel { get; set; } = NoiseModel.Ideal; + public NoiseModel NoiseModel { get; set; } = + NoiseModel.TryGetByName("ideal", out var ideal) + ? ideal + : throw new Exception("Could not load ideal noise model."); } } diff --git a/src/Kernel/Magic/NoiseModel.cs b/src/Kernel/Magic/NoiseModel.cs index c108505a95..49c096c11b 100644 --- a/src/Kernel/Magic/NoiseModel.cs +++ b/src/Kernel/Magic/NoiseModel.cs @@ -46,6 +46,12 @@ This magic command allows accessing or modifying the noise model used by In []: %experimental.noise_model ``` ".Dedent(), + @" + Sets the noise model to a built-in named noise model: + ``` + In []: %experimental.noise_model --load-by-name ideal_stabilizer + ``` + ".Dedent(), @" Set the noise model to a noise model given as JSON: ``` @@ -98,6 +104,18 @@ public override ExecutionResult Run(string input, IChannel channel) var filename = parts[1]; NoiseModelSource.NoiseModel = JsonSerializer.Deserialize(File.ReadAllText(filename)); } + else if (command.Trim() == "--load-by-name") + { + var name = parts[1]; + if (NoiseModel.TryGetByName(name, out var noiseModel)) + { + NoiseModelSource.NoiseModel = noiseModel; + } + else + { + return $"No built-in noise model with name {name}.".ToExecutionResult(ExecuteStatus.Error); + } + } else if (input.Trim().StartsWith("{")) { // Parse the input as JSON. From f97f60807058bd70a588b7778727d313b42ca2ab Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 4 Jun 2021 12:44:46 -0700 Subject: [PATCH 25/43] Revert accidental changes. --- src/Tool/Telemetry.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tool/Telemetry.cs b/src/Tool/Telemetry.cs index 4a1add898f..30ea18dea3 100644 --- a/src/Tool/Telemetry.cs +++ b/src/Tool/Telemetry.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// #if TELEMETRY +#if TELEMETRY using System; using System.IO; @@ -249,4 +249,4 @@ public static EventProperties AsTelemetryEvent(this ExecutedEventArgs info) } -// #endif +#endif From dbcb86980d8fbbd44fdfa6fc26014e16c1e71db9 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 4 Jun 2021 18:13:02 -0700 Subject: [PATCH 26/43] Allow getting/setting noise models by name, add docs. --- src/Kernel/Magic/NoiseModel.cs | 18 +++++ src/Kernel/Magic/SimulateNoise.cs | 11 ++- src/Python/qsharp-core/qsharp/experimental.py | 75 ++++++++++++++++--- 3 files changed, 92 insertions(+), 12 deletions(-) diff --git a/src/Kernel/Magic/NoiseModel.cs b/src/Kernel/Magic/NoiseModel.cs index 49c096c11b..8feb4f06b1 100644 --- a/src/Kernel/Magic/NoiseModel.cs +++ b/src/Kernel/Magic/NoiseModel.cs @@ -46,6 +46,12 @@ This magic command allows accessing or modifying the noise model used by In []: %experimental.noise_model ``` ".Dedent(), + @" + Return the built-in noise model with a given name: + ``` + In []: %experimental.noise_model --get-by-name ideal + ``` + ", @" Sets the noise model to a built-in named noise model: ``` @@ -104,6 +110,18 @@ public override ExecutionResult Run(string input, IChannel channel) var filename = parts[1]; NoiseModelSource.NoiseModel = JsonSerializer.Deserialize(File.ReadAllText(filename)); } + else if (command.Trim() == "--get-by-name") + { + var name = parts[1]; + if (NoiseModel.TryGetByName(name, out var noiseModel)) + { + return noiseModel.ToExecutionResult(); + } + else + { + return $"No built-in noise model with name {name}.".ToExecutionResult(ExecuteStatus.Error); + } + } else if (command.Trim() == "--load-by-name") { var name = parts[1]; diff --git a/src/Kernel/Magic/SimulateNoise.cs b/src/Kernel/Magic/SimulateNoise.cs index ab481abded..77b9050f6a 100644 --- a/src/Kernel/Magic/SimulateNoise.cs +++ b/src/Kernel/Magic/SimulateNoise.cs @@ -43,6 +43,7 @@ will perform when run on noisy quantum hardware. #### See also + - [`%config`](https://docs.microsoft.com/qsharp/api/iqsharp-magic/config) - [`%experimental.noise_model`](https://docs.microsoft.com/qsharp/api/iqsharp-magic/experimental.noise_model) #### Required parameters @@ -50,6 +51,11 @@ will perform when run on noisy quantum hardware. - Q# operation or function name. This must be the first parameter, and must be a valid Q# operation or function name that has been defined either in the notebook or in a Q# file in the same folder. - Arguments for the Q# operation or function must also be specified as `key=value` pairs. + + #### Remarks + + The behavior of this magic command can be controlled through the `%experimental.noise_model` magic command, + and the `opensim.nQubits` and `opensim.representation` configuration settings. ".Dedent(), Examples = new string[] { @@ -109,7 +115,10 @@ public async Task RunAsync(string input, IChannel channel) var symbol = SymbolResolver.Resolve(name) as dynamic; // FIXME: Should be IQSharpSymbol. if (symbol == null) throw new InvalidOperationException($"Invalid operation name: {name}"); - var qsim = new OpenSystemsSimulator(ConfigurationSource.OpenSystemsSimulatorCapacity); + var qsim = new OpenSystemsSimulator( + ConfigurationSource.OpenSystemsSimulatorCapacity //, + // ConfigurationSource.OpenSystemsSimulatorRepresentation + ); if (NoiseModelSource.NoiseModel != null) { var json = JsonSerializer.Serialize(NoiseModelSource.NoiseModel); diff --git a/src/Python/qsharp-core/qsharp/experimental.py b/src/Python/qsharp-core/qsharp/experimental.py index e3f13fd217..e0f2e5fed9 100644 --- a/src/Python/qsharp-core/qsharp/experimental.py +++ b/src/Python/qsharp-core/qsharp/experimental.py @@ -7,6 +7,11 @@ # Licensed under the MIT License. ## +""" +This module allow for using experimental features of the Quantum Development Kit, +including noisy simulators for Q# programs. +""" + ## DESIGN NOTES ## # The functions in this module may take dependencies on QuTiP and NumPy, @@ -29,13 +34,26 @@ __all__ = [ "enable_noisy_simulation", "get_noise_model", - "set_noise_model" + "set_noise_model", + "get_noise_model_by_name", + "set_noise_model_by_name" ] -## FUNCTIONS ## +## PUBLIC FUNCTIONS ## def enable_noisy_simulation(): - # Try to import optional packages used by noise modelling. + """ + Enables the `.simulate_noise` method to be used on Python objects + representing Q# operations, allowing for Q# programs to be simulated using + experimental simulators. + + Noisy simulation is controlled by the :func:`~qsharp.experimental.get_noise_model`, + :func:`~qsharp.experimental.set_noise_model` and :func:`~qsharp.experimental.set_noise_model_by_name` + functions, and by the `opensim.nQubits` and `opensim.representation` keys + of the :any:`qsharp.config` object. + """ + + # Try to import optional packages used by noise modeling. optional_dependencies = [] try: import numpy as np @@ -60,10 +78,53 @@ def enable_noisy_simulation(): except: pass + # Actually attach the new method to the type used for exposing Q# callables + # to Python. def simulate_noise(self, **kwargs): return qsharp.client._simulate_noise(self, **kwargs) + QSharpCallable.simulate_noise = simulate_noise + +def get_noise_model(): + """ + Returns the current noise model used in simulating Q# programs with the + `.simulate_noise` method. + """ + noise_model = convert_to_arrays(qsharp.client._get_noise_model()) + # Convert {"Mixed": ...} and so forth to qobj. + return convert_to_qobjs(noise_model) + +def get_noise_model_by_name(name: str): + """ + Returns the built-in noise model with a given name. + + :param name: The name of the noise model to be returned (either `ideal` + or `ideal_stabilizer`). + """ + noise_model = convert_to_arrays(qsharp.client._get_noise_model_by_name(name)) + # Convert {"Mixed": ...} and so forth to qobj. + return convert_to_qobjs(noise_model) + +def set_noise_model(noise_model): + """ + Sets the current noise model used in simulating Q# programs with the + `.simulate_noise` method. + """ + qsharp.client._set_noise_model(json.dumps(convert_to_rust_style(noise_model))) + +def set_noise_model_by_name(name): + """ + Sets the current noise model used in simulating Q# programs with the + `.simulate_noise` method to a built-in noise model, given by name. + + :param name: The name of the noise model to be returned (either `ideal` + or `ideal_stabilizer`). + """ + qsharp.client._set_noise_model_by_name(name) + +## PRIVATE FUNCTIONS ## + def is_rust_style_array(json_obj): return ( isinstance(json_obj, dict) and @@ -180,11 +241,3 @@ def convert_to_rust_style(json_obj, expect_state=False): json_obj ) - -def get_noise_model(): - noise_model = convert_to_arrays(qsharp.client._get_noise_model()) - # Convert {"Mixed": ...} and so forth to qobj. - return convert_to_qobjs(noise_model) - -def set_noise_model(noise_model): - qsharp.client._set_noise_model(json.dumps(convert_to_rust_style(noise_model))) From 22e7d739a4755ed402f106404029caff5bf47a3d Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Mon, 7 Jun 2021 15:48:05 -0700 Subject: [PATCH 27/43] Expose representations and named noise models. --- src/Jupyter/ConfigurationSource/IConfigurationSource.cs | 7 +++++++ src/Kernel/Magic/SimulateNoise.cs | 4 ++-- src/Python/qsharp-core/qsharp/clients/iqsharp.py | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Jupyter/ConfigurationSource/IConfigurationSource.cs b/src/Jupyter/ConfigurationSource/IConfigurationSource.cs index 7e2a08d5cb..d8d83790e0 100644 --- a/src/Jupyter/ConfigurationSource/IConfigurationSource.cs +++ b/src/Jupyter/ConfigurationSource/IConfigurationSource.cs @@ -136,5 +136,12 @@ public T GetOptionOrDefault(string optionName, T defaultValue) => ///
public uint OpenSystemsSimulatorCapacity => GetOptionOrDefault("opensim.nQubits", 3); + + /// + /// Specifies the representation to use for the initial state + /// when simulating Q# programs with experimental simulators. + /// + public string OpenSystemsSimulatorRepresentation => + GetOptionOrDefault("opensim.representation", "mixed"); } } diff --git a/src/Kernel/Magic/SimulateNoise.cs b/src/Kernel/Magic/SimulateNoise.cs index 77b9050f6a..35c8ab7255 100644 --- a/src/Kernel/Magic/SimulateNoise.cs +++ b/src/Kernel/Magic/SimulateNoise.cs @@ -116,8 +116,8 @@ public async Task RunAsync(string input, IChannel channel) if (symbol == null) throw new InvalidOperationException($"Invalid operation name: {name}"); var qsim = new OpenSystemsSimulator( - ConfigurationSource.OpenSystemsSimulatorCapacity //, - // ConfigurationSource.OpenSystemsSimulatorRepresentation + ConfigurationSource.OpenSystemsSimulatorCapacity, + ConfigurationSource.OpenSystemsSimulatorRepresentation ); if (NoiseModelSource.NoiseModel != null) { diff --git a/src/Python/qsharp-core/qsharp/clients/iqsharp.py b/src/Python/qsharp-core/qsharp/clients/iqsharp.py index 2e8aae4791..03ce50f4d7 100644 --- a/src/Python/qsharp-core/qsharp/clients/iqsharp.py +++ b/src/Python/qsharp-core/qsharp/clients/iqsharp.py @@ -215,6 +215,14 @@ def _set_noise_model(self, json_data : str) -> None: # provided by _execute_magic and call directly. return self._execute(f'%experimental.noise_model {json_data}') + def _set_noise_model(self, json_data : str) -> None: + # We assume json_data is already serialized, so that we skip the support + # provided by _execute_magic and call directly. + return self._execute(f'%experimental.noise_model {json_data}') + + def _set_noise_model_by_name(self, name : str) -> None: + return self._execute(f'%experimental.noise_model --load-by-name {name}') + ## Internal-Use Methods ## From 104bcfbcee2342d2d912ab04ddcd1c82a294aebb Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Mon, 7 Jun 2021 16:10:27 -0700 Subject: [PATCH 28/43] Update package versions to latest alpha build. --- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/Tool.csproj | 1 + src/Tool/appsettings.json | 32 +++++++++---------- 9 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 734e6ef55f..3e198fa3ab 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index 33ce400d90..40b83f8874 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - +
diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index afe98d8a65..e364c30435 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index afe98d8a65..e364c30435 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index c6d826fb0c..f05eba47ca 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 14ed83b406..8527f30028 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index fead303bdd..75d0fab27b 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/Tool.csproj b/src/Tool/Tool.csproj index 5872a1cf2e..d63fff8e0e 100644 --- a/src/Tool/Tool.csproj +++ b/src/Tool/Tool.csproj @@ -49,6 +49,7 @@ + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 9447ad4bc1..816de655d1 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.17.210627536-alpha", + "Microsoft.Quantum.Compiler::0.17.210627637-alpha", - "Microsoft.Quantum.CSharpGeneration::0.17.210627536-alpha", - "Microsoft.Quantum.Development.Kit::0.17.210627536-alpha", - "Microsoft.Quantum.Simulators::0.17.210627536-alpha", - "Microsoft.Quantum.Xunit::0.17.210627536-alpha", + "Microsoft.Quantum.CSharpGeneration::0.17.210627637-alpha", + "Microsoft.Quantum.Development.Kit::0.17.210627637-alpha", + "Microsoft.Quantum.Simulators::0.17.210627637-alpha", + "Microsoft.Quantum.Xunit::0.17.210627637-alpha", - "Microsoft.Quantum.Standard::0.17.210627536-alpha", - "Microsoft.Quantum.Standard.Visualization::0.17.210627536-alpha", - "Microsoft.Quantum.Chemistry::0.17.210627536-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627536-alpha", - "Microsoft.Quantum.MachineLearning::0.17.210627536-alpha", - "Microsoft.Quantum.Numerics::0.17.210627536-alpha", + "Microsoft.Quantum.Standard::0.17.210627637-alpha", + "Microsoft.Quantum.Standard.Visualization::0.17.210627637-alpha", + "Microsoft.Quantum.Chemistry::0.17.210627637-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627637-alpha", + "Microsoft.Quantum.MachineLearning::0.17.210627637-alpha", + "Microsoft.Quantum.Numerics::0.17.210627637-alpha", - "Microsoft.Quantum.Katas::0.17.210627536-alpha", + "Microsoft.Quantum.Katas::0.17.210627637-alpha", - "Microsoft.Quantum.Research::0.17.210627536-alpha", + "Microsoft.Quantum.Research::0.17.210627637-alpha", - "Microsoft.Quantum.Providers.IonQ::0.17.210627536-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.17.210627536-alpha", - "Microsoft.Quantum.Providers.QCI::0.17.210627536-alpha" + "Microsoft.Quantum.Providers.IonQ::0.17.210627637-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.17.210627637-alpha", + "Microsoft.Quantum.Providers.QCI::0.17.210627637-alpha" ] } From 1490e94676665fc4f65fa5e5d95b3e78b9dd9643 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 8 Jun 2021 10:27:46 -0700 Subject: [PATCH 29/43] Update to latest build. --- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/appsettings.json | 32 +++++++++---------- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 3e198fa3ab..db4676a461 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index 40b83f8874..ddcd2d90fc 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index e364c30435..01a96c3224 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index e364c30435..01a96c3224 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index f05eba47ca..f8b019e593 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 8527f30028..1199ce8cf0 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index 75d0fab27b..efa9ac7729 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 816de655d1..92fd97de89 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.17.210627637-alpha", + "Microsoft.Quantum.Compiler::0.17.210627692-alpha", - "Microsoft.Quantum.CSharpGeneration::0.17.210627637-alpha", - "Microsoft.Quantum.Development.Kit::0.17.210627637-alpha", - "Microsoft.Quantum.Simulators::0.17.210627637-alpha", - "Microsoft.Quantum.Xunit::0.17.210627637-alpha", + "Microsoft.Quantum.CSharpGeneration::0.17.210627692-alpha", + "Microsoft.Quantum.Development.Kit::0.17.210627692-alpha", + "Microsoft.Quantum.Simulators::0.17.210627692-alpha", + "Microsoft.Quantum.Xunit::0.17.210627692-alpha", - "Microsoft.Quantum.Standard::0.17.210627637-alpha", - "Microsoft.Quantum.Standard.Visualization::0.17.210627637-alpha", - "Microsoft.Quantum.Chemistry::0.17.210627637-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627637-alpha", - "Microsoft.Quantum.MachineLearning::0.17.210627637-alpha", - "Microsoft.Quantum.Numerics::0.17.210627637-alpha", + "Microsoft.Quantum.Standard::0.17.210627692-alpha", + "Microsoft.Quantum.Standard.Visualization::0.17.210627692-alpha", + "Microsoft.Quantum.Chemistry::0.17.210627692-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627692-alpha", + "Microsoft.Quantum.MachineLearning::0.17.210627692-alpha", + "Microsoft.Quantum.Numerics::0.17.210627692-alpha", - "Microsoft.Quantum.Katas::0.17.210627637-alpha", + "Microsoft.Quantum.Katas::0.17.210627692-alpha", - "Microsoft.Quantum.Research::0.17.210627637-alpha", + "Microsoft.Quantum.Research::0.17.210627692-alpha", - "Microsoft.Quantum.Providers.IonQ::0.17.210627637-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.17.210627637-alpha", - "Microsoft.Quantum.Providers.QCI::0.17.210627637-alpha" + "Microsoft.Quantum.Providers.IonQ::0.17.210627692-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.17.210627692-alpha", + "Microsoft.Quantum.Providers.QCI::0.17.210627692-alpha" ] } From ace7b9aeefdcaa3845cf80180d7a3a79e941aa5f Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 8 Jun 2021 10:28:35 -0700 Subject: [PATCH 30/43] Improve visualization and serialization. --- .../IConfigurationSource.cs | 19 ++- .../Visualization/OpenSystemsEncoders.cs | 124 ++++++++++++++++++ src/Kernel/Magic/SimulateNoise.cs | 5 +- .../qsharp-core/qsharp/clients/iqsharp.py | 8 +- src/Python/qsharp-core/qsharp/experimental.py | 29 +++- 5 files changed, 165 insertions(+), 20 deletions(-) diff --git a/src/Jupyter/ConfigurationSource/IConfigurationSource.cs b/src/Jupyter/ConfigurationSource/IConfigurationSource.cs index d8d83790e0..4b33e1e1a9 100644 --- a/src/Jupyter/ConfigurationSource/IConfigurationSource.cs +++ b/src/Jupyter/ConfigurationSource/IConfigurationSource.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using Microsoft.Quantum.Experimental; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -131,17 +132,23 @@ public T GetOptionOrDefault(string optionName, T defaultValue) => GetOptionOrDefault("trace.style", TraceVisualizationStyle.Default); /// - /// Specifies the number of qubits that the open systems simulator - /// supports for use in running Q# programs. + /// Specifies the number of qubits that the experimental simulators + /// support for use in running Q# programs. /// - public uint OpenSystemsSimulatorCapacity => - GetOptionOrDefault("opensim.nQubits", 3); + public uint ExperimentalSimulatorCapacity => + GetOptionOrDefault("experimental.simulators.nQubits", 3); /// /// Specifies the representation to use for the initial state /// when simulating Q# programs with experimental simulators. /// - public string OpenSystemsSimulatorRepresentation => - GetOptionOrDefault("opensim.representation", "mixed"); + public string ExperimentalSimulatorRepresentation => + GetOptionOrDefault("experimental.simulators.representation", "mixed"); + + /// + /// Specifies the format used in dumping stabilizer states. + /// + public StabilizerStateVisualizationStyle ExperimentalSimulatorStabilizerStateVisualizationStyle => + GetOptionOrDefault("experimental.simulators.stabilizerStateStyle", StabilizerStateVisualizationStyle.MatrixWithDestabilizers); } } diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs index a8974731fb..c4c978cf3d 100644 --- a/src/Jupyter/Visualization/OpenSystemsEncoders.cs +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -9,9 +9,25 @@ using Microsoft.Jupyter.Core; using Microsoft.Quantum.IQSharp.Jupyter; using System.Collections.Generic; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json; +using System; namespace Microsoft.Quantum.Experimental { + /// + /// Represents different styles for displaying the Q# execution path + /// visualization as HTML. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum StabilizerStateVisualizationStyle + { + MatrixWithDestabilizers, + MatrixWithoutDestabilizers, + DenseGroupPresentation, + SparseGroupPresentation + } + // TODO: add display encoders for other formats. public class MixedStateToHtmlDisplayEncoder : IResultEncoder { @@ -51,6 +67,114 @@ public class MixedStateToHtmlDisplayEncoder : IResultEncoder } } + public class StabilizerStateToHtmlDisplayEncoder : IResultEncoder + { + private readonly IConfigurationSource config; + + /// + public string MimeType => MimeTypes.Html; + + public StabilizerStateToHtmlDisplayEncoder(IConfigurationSource config) + { + this.config = config; + } + + /// + public EncodedData? Encode(object displayable) + { + if (displayable is StabilizerState { NQubits: var nQubits, Data: {} data }) + { + var repeatedCs = new String('c', nQubits); + var colspec = $"{repeatedCs}|{repeatedCs}|c"; + return $@" + + + + + + + + + + + +
Stabilizer state
# of qubits{nQubits}
State data{ + config.ExperimentalSimulatorStabilizerStateVisualizationStyle switch + { + StabilizerStateVisualizationStyle.MatrixWithDestabilizers => + $@"$$\left(\begin{{array}}{{{colspec}}}{ + string.Join( + "\\\\\n", + Enumerable + .Range(0, data.Shape[0]) + .Select( + idxRow => + ( + idxRow == nQubits + ? "\\hline\n" + : "" + ) + string.Join(" & ", + Enumerable.Range(0, data.Shape[1]) + .Select( + idxCol => data[idxRow, idxCol] ? "1" : "0" + ) + ) + ) + ) + }\end{{array}}\right)$$", + StabilizerStateVisualizationStyle.MatrixWithoutDestabilizers => + $@"$$\left(\begin{{array}}{{{colspec}}}{ + string.Join( + "\\\\\n", + Enumerable + .Range(nQubits, data.Shape[0] / 2) + .Select( + idxRow => string.Join(" & ", + Enumerable.Range(0, data.Shape[1]) + .Select( + idxCol => data[idxRow, idxCol] ? "1" : "0" + ) + ) + ) + ) + }\end{{array}}\right)$$", + StabilizerStateVisualizationStyle.DenseGroupPresentation => + $@"$$\left\langle { + string.Join( + ", ", + Enumerable + .Range(nQubits, data.Shape[0] / 2) + .Select( + idxRow => string.Join("", + Enumerable.Range(0, nQubits) + .Select(idxQubit => + { + (bool x, bool z) = (data[idxRow, idxQubit], data[idxRow, nQubits + idxQubit]); + return (x, z) switch + { + (false, false) => "𝟙", + (true, false) => "X", + (false, true) => "Z", + (true, true) => "Y" + }; + }) + ) + ) + ) + } \right\rangle$$", + // "(dense group presentation not yet implemented)", + StabilizerStateVisualizationStyle.SparseGroupPresentation => + "(sparse group presentation not yet implemented)", + var unknown => throw new Exception($"Invalid visualization style {unknown}.") + } + }
+ " + .ToEncodedData(); + } + else return null; + } + } + public class NoiseModelToHtmlDisplayEncoder : IResultEncoder { /// diff --git a/src/Kernel/Magic/SimulateNoise.cs b/src/Kernel/Magic/SimulateNoise.cs index 35c8ab7255..b093383939 100644 --- a/src/Kernel/Magic/SimulateNoise.cs +++ b/src/Kernel/Magic/SimulateNoise.cs @@ -84,6 +84,7 @@ and the `opensim.nQubits` and `opensim.representation` configuration settings. if (engine is IQSharpEngine iQSharpEngine) { iQSharpEngine.RegisterDisplayEncoder(new MixedStateToHtmlDisplayEncoder()); + iQSharpEngine.RegisterDisplayEncoder(new StabilizerStateToHtmlDisplayEncoder(configurationSource)); } } @@ -116,8 +117,8 @@ public async Task RunAsync(string input, IChannel channel) if (symbol == null) throw new InvalidOperationException($"Invalid operation name: {name}"); var qsim = new OpenSystemsSimulator( - ConfigurationSource.OpenSystemsSimulatorCapacity, - ConfigurationSource.OpenSystemsSimulatorRepresentation + ConfigurationSource.ExperimentalSimulatorCapacity, + ConfigurationSource.ExperimentalSimulatorRepresentation ); if (NoiseModelSource.NoiseModel != null) { diff --git a/src/Python/qsharp-core/qsharp/clients/iqsharp.py b/src/Python/qsharp-core/qsharp/clients/iqsharp.py index 03ce50f4d7..e4d05914bb 100644 --- a/src/Python/qsharp-core/qsharp/clients/iqsharp.py +++ b/src/Python/qsharp-core/qsharp/clients/iqsharp.py @@ -208,12 +208,10 @@ def _simulate_noise(self, op, **kwargs) -> Any: return self._execute_callable_magic('experimental.simulate_noise', op, **kwargs) def _get_noise_model(self) -> str: - return self._execute('%experimental.noise_model') + return self._execute(f'%experimental.noise_model') - def _set_noise_model(self, json_data : str) -> None: - # We assume json_data is already serialized, so that we skip the support - # provided by _execute_magic and call directly. - return self._execute(f'%experimental.noise_model {json_data}') + def _get_noise_model_by_name(self, name : str) -> None: + return self._execute(f'%experimental.noise_model --get-by-name {name}') def _set_noise_model(self, json_data : str) -> None: # We assume json_data is already serialized, so that we skip the support diff --git a/src/Python/qsharp-core/qsharp/experimental.py b/src/Python/qsharp-core/qsharp/experimental.py index e0f2e5fed9..c16880aa14 100644 --- a/src/Python/qsharp-core/qsharp/experimental.py +++ b/src/Python/qsharp-core/qsharp/experimental.py @@ -25,6 +25,7 @@ ## IMPORTS ## +from typing import FrozenSet import qsharp from qsharp.loader import QSharpCallable import json @@ -125,6 +126,8 @@ def set_noise_model_by_name(name): ## PRIVATE FUNCTIONS ## +literal_keys = frozenset(['ChpDecomposition']) + def is_rust_style_array(json_obj): return ( isinstance(json_obj, dict) and @@ -134,25 +137,34 @@ def is_rust_style_array(json_obj): json_obj['v'] == 1 ) -def rust_style_array_as_array(json_obj): +def rust_style_array_as_array(json_obj, as_complex : bool = True): import numpy as np - arr = np.array(json_obj['data']).reshape(json_obj['dim'] + [2]).astype(complex) - return arr[..., 0] + 1j * arr[..., 1] - -def convert_to_arrays(json_obj): + dims = json_obj['dim'] + [2] if as_complex else json_obj['dim'] + arr = np.array(json_obj['data']).reshape(dims) + if as_complex: + arr = arr.astype(complex) + return arr[..., 0] + 1j * arr[..., 1] + else: + return arr + +def convert_to_arrays(json_obj, as_complex : bool = True): return ( # Add on a trailing index of length 2. - rust_style_array_as_array(json_obj) + rust_style_array_as_array(json_obj, as_complex=as_complex) if is_rust_style_array(json_obj) else { key: - convert_to_arrays(value) + value + if key in literal_keys else + + convert_to_arrays(value, as_complex=key != 'table') if isinstance(value, dict) else [convert_to_arrays(element) for element in value] if isinstance(value, list) else value + for key, value in json_obj.items() } ) @@ -176,6 +188,9 @@ def convert_to_qobjs(json_obj): { key: + value + if key in literal_keys else + # Recurse if needed... convert_to_qobjs(value) if isinstance(value, dict) else From cdce975b21c6949d1fbf5c3216ab3bd5fb4736c9 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 8 Jun 2021 13:37:41 -0700 Subject: [PATCH 31/43] Update to latest build. --- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/Tool.csproj | 1 - src/Tool/appsettings.json | 32 +++++++++---------- 9 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index db4676a461..8825688aa7 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index ddcd2d90fc..aef2ba5507 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index 01a96c3224..0196cf8c68 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index 01a96c3224..0196cf8c68 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index f8b019e593..a0c6721ed0 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 1199ce8cf0..1cea076a1f 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index efa9ac7729..a4c8d8494e 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/Tool.csproj b/src/Tool/Tool.csproj index d63fff8e0e..5872a1cf2e 100644 --- a/src/Tool/Tool.csproj +++ b/src/Tool/Tool.csproj @@ -49,7 +49,6 @@ - diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 92fd97de89..5d8fa9e545 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.17.210627692-alpha", + "Microsoft.Quantum.Compiler::0.17.210627706-alpha", - "Microsoft.Quantum.CSharpGeneration::0.17.210627692-alpha", - "Microsoft.Quantum.Development.Kit::0.17.210627692-alpha", - "Microsoft.Quantum.Simulators::0.17.210627692-alpha", - "Microsoft.Quantum.Xunit::0.17.210627692-alpha", + "Microsoft.Quantum.CSharpGeneration::0.17.210627706-alpha", + "Microsoft.Quantum.Development.Kit::0.17.210627706-alpha", + "Microsoft.Quantum.Simulators::0.17.210627706-alpha", + "Microsoft.Quantum.Xunit::0.17.210627706-alpha", - "Microsoft.Quantum.Standard::0.17.210627692-alpha", - "Microsoft.Quantum.Standard.Visualization::0.17.210627692-alpha", - "Microsoft.Quantum.Chemistry::0.17.210627692-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627692-alpha", - "Microsoft.Quantum.MachineLearning::0.17.210627692-alpha", - "Microsoft.Quantum.Numerics::0.17.210627692-alpha", + "Microsoft.Quantum.Standard::0.17.210627706-alpha", + "Microsoft.Quantum.Standard.Visualization::0.17.210627706-alpha", + "Microsoft.Quantum.Chemistry::0.17.210627706-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627706-alpha", + "Microsoft.Quantum.MachineLearning::0.17.210627706-alpha", + "Microsoft.Quantum.Numerics::0.17.210627706-alpha", - "Microsoft.Quantum.Katas::0.17.210627692-alpha", + "Microsoft.Quantum.Katas::0.17.210627706-alpha", - "Microsoft.Quantum.Research::0.17.210627692-alpha", + "Microsoft.Quantum.Research::0.17.210627706-alpha", - "Microsoft.Quantum.Providers.IonQ::0.17.210627692-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.17.210627692-alpha", - "Microsoft.Quantum.Providers.QCI::0.17.210627692-alpha" + "Microsoft.Quantum.Providers.IonQ::0.17.210627706-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.17.210627706-alpha", + "Microsoft.Quantum.Providers.QCI::0.17.210627706-alpha" ] } From 19cd817fdb66bfd43dd94aa38cc9bae350d21952 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 8 Jun 2021 18:33:41 -0700 Subject: [PATCH 32/43] Add Python magics, expose experimental build info to Python. --- src/Python/qsharp-core/qsharp/__init__.py | 13 ++ src/Python/qsharp-core/qsharp/experimental.py | 158 +++++++++++++++++- .../qsharp-core/qsharp/ipython_magic.py | 38 +++++ 3 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 src/Python/qsharp-core/qsharp/ipython_magic.py diff --git a/src/Python/qsharp-core/qsharp/__init__.py b/src/Python/qsharp-core/qsharp/__init__.py index 133f3ad376..7a19152e4d 100644 --- a/src/Python/qsharp-core/qsharp/__init__.py +++ b/src/Python/qsharp-core/qsharp/__init__.py @@ -115,6 +115,9 @@ def component_versions() -> Dict[str, LooseVersion]: versions = client.component_versions() # Add in the qsharp Python package itself. versions["qsharp"] = LooseVersion(__version__) + # If any experimental features are enabled, report them here. + if _experimental_versions is not None: + versions['experimental'] = _experimental_versions return versions @@ -124,11 +127,21 @@ def component_versions() -> Dict[str, LooseVersion]: config = Config(client) packages = Packages(client) projects = Projects(client) +_experimental_versions = None # Make sure that we're last on the meta_path so that actual modules are loaded # first. sys.meta_path.append(QSharpModuleFinder()) +# If using IPython, forward some useful IQ# magic commands as IPython magic +# commands and define a couple new magic commands for IPython. +try: + if __IPYTHON__: + import qsharp.ipython_magic + qsharp.ipython_magic.register_magics() +except NameError: + pass + # Needed to recognize PEP 420 packages as subpackages. import pkg_resources pkg_resources.declare_namespace(__name__) \ No newline at end of file diff --git a/src/Python/qsharp-core/qsharp/experimental.py b/src/Python/qsharp-core/qsharp/experimental.py index c16880aa14..da1c4d1774 100644 --- a/src/Python/qsharp-core/qsharp/experimental.py +++ b/src/Python/qsharp-core/qsharp/experimental.py @@ -25,10 +25,15 @@ ## IMPORTS ## -from typing import FrozenSet +from typing import Any, FrozenSet, List, Tuple import qsharp from qsharp.loader import QSharpCallable import json +import dataclasses + +from typing import Any, Union + +from qsharp.types import Pauli ## EXPORTS ## @@ -37,7 +42,20 @@ "get_noise_model", "set_noise_model", "get_noise_model_by_name", - "set_noise_model_by_name" + "set_noise_model_by_name", + + # SequenceProcess process data model + "SequenceProcess", + + # Mixed pauli data model + "MixedPauli", + + # CHP decomposition data model + "ChpDecompositionProcess", + "Hadamard", + "Cnot", + "Phase", + "AdjointPhase" ] ## PUBLIC FUNCTIONS ## @@ -53,6 +71,8 @@ def enable_noisy_simulation(): functions, and by the `opensim.nQubits` and `opensim.representation` keys of the :any:`qsharp.config` object. """ + # Prevent Python from thinking that qsharp is a local variable. + import qsharp # Try to import optional packages used by noise modeling. optional_dependencies = [] @@ -86,6 +106,22 @@ def simulate_noise(self, **kwargs): QSharpCallable.simulate_noise = simulate_noise + # Register the experimental feature with qsharp.component_versions so that + # it shows up in notebooks nicely. + version = {'simulators': qsharp.client._execute('%experimental.build_info')} + if qsharp._experimental_versions is not None: + qsharp._experimental_versions.update(version) + else: + qsharp._experimental_versions = version + + # Finally, if we're in IPython, expose experimental magic commands to + # the notebook interface. + try: + if __IPYTHON__: + import qsharp.ipython_magic + qsharp.ipython_magic.register_experimental_magics() + except NameError: + pass def get_noise_model(): """ @@ -112,7 +148,8 @@ def set_noise_model(noise_model): Sets the current noise model used in simulating Q# programs with the `.simulate_noise` method. """ - qsharp.client._set_noise_model(json.dumps(convert_to_rust_style(noise_model))) + json_data = dumps(convert_to_rust_style(noise_model)) + qsharp.client._set_noise_model(json_data) def set_noise_model_by_name(name): """ @@ -124,10 +161,125 @@ def set_noise_model_by_name(name): """ qsharp.client._set_noise_model_by_name(name) +## PUBLIC DATA MODEL ## + +@dataclasses.dataclass +class SequenceProcess(): + n_qubits: int + processes: List[Any] + + def _as_jobj(self): + return { + 'n_qubits': self.n_qubits, + 'data': { + "Sequence": list(map(_as_jobj, self.processes)) + } + } + +@dataclasses.dataclass +class Hadamard(): + idx_target: int + + def _as_jobj(self): + return { + 'Hadamard': self.idx_target + } + +@dataclasses.dataclass +class Phase(): + idx_target: int + + def _as_jobj(self): + return { + 'Phase': self.idx_target + } + +@dataclasses.dataclass +class AdjointPhase(): + idx_target: int + + def _as_jobj(self): + return { + 'AdjointPhase': self.idx_target + } + +@dataclasses.dataclass +class Cnot(): + idx_control: int + idx_target: int + + def _as_jobj(self): + return { + 'Cnot': [self.idx_control, self.idx_target] + } + +@dataclasses.dataclass +class ChpDecompositionProcess(): + n_qubits: int + operations: List[Union[Hadamard, Cnot, Phase, AdjointPhase]] + + def _as_jobj(self): + return { + 'n_qubits': self.n_qubits, + 'data': { + 'ChpDecomposition': list(map(_as_jobj, self.operations)) + } + } + +@dataclasses.dataclass +class MixedPauliProcess(): + n_qubits: int + operators: List[Tuple[float, Union[List[qsharp.Pauli]], str]] + + def _as_jobj(self): + return { + 'n_qubits': self.n_qubits, + 'data': { + 'MixedPauli': [ + [ + pr, + [ + str(qsharp.Pauli[p] if isinstance(p, str) else qsharp.Pauli(p)) + for p in ops + ] + ] + for (pr, ops) in self.operators + ] + } + } + ## PRIVATE FUNCTIONS ## literal_keys = frozenset(['ChpDecomposition']) +def _as_jobj(o, default=lambda x: x): + import numpy as np + if isinstance(o, np.ndarray): + # Use Rust-style arrays. + return { + 'v': 1, + 'dim': list(o.shape), + 'data': o.reshape((-1, )).tolist() + } + elif hasattr(o, '_as_jobj'): + return o._as_jobj() + + return default(o) + +class NoiseModelEncoder(json.JSONEncoder): + def default(self, o: Any) -> Any: + return _as_jobj(o, super().default) + +def dumps(obj: Any) -> str: + """ + Wraps json.dumps with a custom JSONEncoder class to cover types used in + noise model serialization. + """ + return json.dumps( + obj=obj, + cls=NoiseModelEncoder + ) + def is_rust_style_array(json_obj): return ( isinstance(json_obj, dict) and diff --git a/src/Python/qsharp-core/qsharp/ipython_magic.py b/src/Python/qsharp-core/qsharp/ipython_magic.py new file mode 100644 index 0000000000..7c0e9550b3 --- /dev/null +++ b/src/Python/qsharp-core/qsharp/ipython_magic.py @@ -0,0 +1,38 @@ +#!/bin/env python +# -*- coding: utf-8 -*- +## +# ipython_magic.py: Integration into the IPython notebook environment. +## +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +## + +# NB: This should ONLY be imported from an IPython session. + +import qsharp as qs +from IPython.display import display +from IPython.core.magic import (register_line_magic, register_cell_magic, + register_line_cell_magic, needs_local_scope) + + +def register_magics(): + @register_cell_magic + @needs_local_scope + def qsharp(magic_args, cell, local_ns=None): + """Compiles a Q# snippet, exposing its operations and functions to + the current local scope.""" + callables = qs.compile(cell) + if isinstance(callables, qs.QSharpCallable): + local_ns[callables._name] = callables + else: + for qs_callable in callables: + local_ns[qs_callable.name] = qs_callable + +def register_experimental_magics(): + import qsharp.experimental as exp + + @register_line_magic + def noise_model(line): + args = line.split(' ') + if args[0] == '--set-by-name': + exp.set_noise_model_by_name(args[1]) From 2035f01f086c7c1f4e4f43d1a0b33f73995c38fd Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 8 Jun 2021 18:34:01 -0700 Subject: [PATCH 33/43] Display encoder for sparse stabilizer states. --- .../Visualization/OpenSystemsEncoders.cs | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs index c4c978cf3d..5729f46511 100644 --- a/src/Jupyter/Visualization/OpenSystemsEncoders.cs +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -160,9 +160,30 @@ public StabilizerStateToHtmlDisplayEncoder(IConfigurationSource config) ) ) } \right\rangle$$", - // "(dense group presentation not yet implemented)", StabilizerStateVisualizationStyle.SparseGroupPresentation => - "(sparse group presentation not yet implemented)", + $@"$$\left\langle { + string.Join( + ", ", + Enumerable + .Range(nQubits, data.Shape[0] / 2) + .Select( + idxRow => string.Join("", + Enumerable.Range(0, nQubits) + .Select(idxQubit => + { + (bool x, bool z) = (data[idxRow, idxQubit], data[idxRow, nQubits + idxQubit]); + return (x, z) switch + { + (false, false) => "", + (true, false) => $"X_{{{idxQubit}}}", + (false, true) => $"Z_{{{idxQubit}}}", + (true, true) => $"Y_{{{idxQubit}}}" + }; + }) + ) + ) + ) + } \right\rangle$$", var unknown => throw new Exception($"Invalid visualization style {unknown}.") } } From 11b527e0a17f67d2db93f6dd82ef0ffbfc8d56ff Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 8 Jun 2021 18:34:13 -0700 Subject: [PATCH 34/43] Build info as a magic command. --- src/Kernel/Magic/ExperimentalBuildInfo.cs | 56 +++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/Kernel/Magic/ExperimentalBuildInfo.cs diff --git a/src/Kernel/Magic/ExperimentalBuildInfo.cs b/src/Kernel/Magic/ExperimentalBuildInfo.cs new file mode 100644 index 0000000000..62bad634b8 --- /dev/null +++ b/src/Kernel/Magic/ExperimentalBuildInfo.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +using System; +using System.IO; +using System.Threading.Tasks; +using Microsoft.Jupyter.Core; +using Microsoft.Quantum.IQSharp; +using Microsoft.Quantum.IQSharp.Common; +using Microsoft.Quantum.IQSharp.Jupyter; +using Microsoft.Quantum.Simulation.Core; +using Microsoft.Quantum.Simulation.Simulators; +using System.Text.Json; +using Microsoft.Extensions.Logging; +using Microsoft.Quantum.IQSharp.Kernel; +using System.Collections.Generic; + +namespace Microsoft.Quantum.Experimental +{ + public class ExperimentalBuildInfoMagic : AbstractMagic + { + + /// + /// Allows for querying noise models and for loading new noise models. + /// + public ExperimentalBuildInfoMagic() : base( + "experimental.build_info", + new Microsoft.Jupyter.Core.Documentation + { + Summary = "Reports build info for the experimental simulators.", + Description = @" + > **⚠ WARNING:** This magic command is **experimental**, + > is not supported, and may be removed from future versions without notice. + ".Dedent(), + Examples = new string[] + { + @" + Return the build info for experimental simulators: + ``` + In []: %experimental.build_info + ``` + ".Dedent(), + } + }) + { } + + /// + public override ExecutionResult Run(string input, IChannel channel) + { + // TODO: call OpenSystemsSimulator.BuildInfo once that is enabled. + return new Dictionary().ToExecutionResult(); + } + } +} From 4a1853d8de26d09b9dd6a969fd3d5d06d9d4223d Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Tue, 8 Jun 2021 18:34:34 -0700 Subject: [PATCH 35/43] Update to latest build. --- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/appsettings.json | 32 +++++++++---------- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 8825688aa7..9de7c5d273 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index aef2ba5507..81bbc83e3b 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index 0196cf8c68..639feb7758 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index 0196cf8c68..639feb7758 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index a0c6721ed0..4f697e9f15 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index 1cea076a1f..a7bcc35634 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index a4c8d8494e..2ec6f1dcc3 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 5d8fa9e545..668f71d759 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.17.210627706-alpha", + "Microsoft.Quantum.Compiler::0.17.210627739-alpha", - "Microsoft.Quantum.CSharpGeneration::0.17.210627706-alpha", - "Microsoft.Quantum.Development.Kit::0.17.210627706-alpha", - "Microsoft.Quantum.Simulators::0.17.210627706-alpha", - "Microsoft.Quantum.Xunit::0.17.210627706-alpha", + "Microsoft.Quantum.CSharpGeneration::0.17.210627739-alpha", + "Microsoft.Quantum.Development.Kit::0.17.210627739-alpha", + "Microsoft.Quantum.Simulators::0.17.210627739-alpha", + "Microsoft.Quantum.Xunit::0.17.210627739-alpha", - "Microsoft.Quantum.Standard::0.17.210627706-alpha", - "Microsoft.Quantum.Standard.Visualization::0.17.210627706-alpha", - "Microsoft.Quantum.Chemistry::0.17.210627706-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627706-alpha", - "Microsoft.Quantum.MachineLearning::0.17.210627706-alpha", - "Microsoft.Quantum.Numerics::0.17.210627706-alpha", + "Microsoft.Quantum.Standard::0.17.210627739-alpha", + "Microsoft.Quantum.Standard.Visualization::0.17.210627739-alpha", + "Microsoft.Quantum.Chemistry::0.17.210627739-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627739-alpha", + "Microsoft.Quantum.MachineLearning::0.17.210627739-alpha", + "Microsoft.Quantum.Numerics::0.17.210627739-alpha", - "Microsoft.Quantum.Katas::0.17.210627706-alpha", + "Microsoft.Quantum.Katas::0.17.210627739-alpha", - "Microsoft.Quantum.Research::0.17.210627706-alpha", + "Microsoft.Quantum.Research::0.17.210627739-alpha", - "Microsoft.Quantum.Providers.IonQ::0.17.210627706-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.17.210627706-alpha", - "Microsoft.Quantum.Providers.QCI::0.17.210627706-alpha" + "Microsoft.Quantum.Providers.IonQ::0.17.210627739-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.17.210627739-alpha", + "Microsoft.Quantum.Providers.QCI::0.17.210627739-alpha" ] } From ce6d5ddb997e2479e052ecd4c96f778afc5aaea2 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 9 Jun 2021 08:31:43 -0700 Subject: [PATCH 36/43] Fix bug in group presentations. --- .../Visualization/OpenSystemsEncoders.cs | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs index 5729f46511..452742e934 100644 --- a/src/Jupyter/Visualization/OpenSystemsEncoders.cs +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -136,6 +136,7 @@ public StabilizerStateToHtmlDisplayEncoder(IConfigurationSource config) ) ) }\end{{array}}\right)$$", + // FIXME: include phases in each! StabilizerStateVisualizationStyle.DenseGroupPresentation => $@"$$\left\langle { string.Join( @@ -143,20 +144,22 @@ public StabilizerStateToHtmlDisplayEncoder(IConfigurationSource config) Enumerable .Range(nQubits, data.Shape[0] / 2) .Select( - idxRow => string.Join("", - Enumerable.Range(0, nQubits) - .Select(idxQubit => - { - (bool x, bool z) = (data[idxRow, idxQubit], data[idxRow, nQubits + idxQubit]); - return (x, z) switch + idxRow => + (data[idxRow, ~1] ? "-" : "") + + string.Join("", + Enumerable.Range(0, nQubits) + .Select(idxQubit => { - (false, false) => "𝟙", - (true, false) => "X", - (false, true) => "Z", - (true, true) => "Y" - }; - }) - ) + (bool x, bool z) = (data[idxRow, idxQubit], data[idxRow, nQubits + idxQubit]); + return (x, z) switch + { + (false, false) => "𝟙", + (true, false) => "X", + (false, true) => "Z", + (true, true) => "Y" + }; + }) + ) ) ) } \right\rangle$$", @@ -167,20 +170,22 @@ public StabilizerStateToHtmlDisplayEncoder(IConfigurationSource config) Enumerable .Range(nQubits, data.Shape[0] / 2) .Select( - idxRow => string.Join("", - Enumerable.Range(0, nQubits) - .Select(idxQubit => - { - (bool x, bool z) = (data[idxRow, idxQubit], data[idxRow, nQubits + idxQubit]); - return (x, z) switch + idxRow => + (data[idxRow, ~1] ? "-" : "") + + string.Join("", + Enumerable.Range(0, nQubits) + .Select(idxQubit => { - (false, false) => "", - (true, false) => $"X_{{{idxQubit}}}", - (false, true) => $"Z_{{{idxQubit}}}", - (true, true) => $"Y_{{{idxQubit}}}" - }; - }) - ) + (bool x, bool z) = (data[idxRow, idxQubit], data[idxRow, nQubits + idxQubit]); + return (x, z) switch + { + (false, false) => "", + (true, false) => $"X_{{{idxQubit}}}", + (false, true) => $"Z_{{{idxQubit}}}", + (true, true) => $"Y_{{{idxQubit}}}" + }; + }) + ) ) ) } \right\rangle$$", From 821f477aab8526a73dcb2562fb2c5de33cd899ca Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 9 Jun 2021 08:31:59 -0700 Subject: [PATCH 37/43] Expose build info. --- src/Kernel/Magic/ExperimentalBuildInfo.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Kernel/Magic/ExperimentalBuildInfo.cs b/src/Kernel/Magic/ExperimentalBuildInfo.cs index 62bad634b8..67c63e4477 100644 --- a/src/Kernel/Magic/ExperimentalBuildInfo.cs +++ b/src/Kernel/Magic/ExperimentalBuildInfo.cs @@ -49,8 +49,7 @@ public ExperimentalBuildInfoMagic() : base( /// public override ExecutionResult Run(string input, IChannel channel) { - // TODO: call OpenSystemsSimulator.BuildInfo once that is enabled. - return new Dictionary().ToExecutionResult(); + return OpenSystemsSimulator.BuildInfo.ToExecutionResult(); } } } From 40df0f48a73f6bf317607589069085bb5d7eed12 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 9 Jun 2021 08:32:10 -0700 Subject: [PATCH 38/43] Fixed bug in mixed pauli process serialization. --- src/Python/qsharp-core/qsharp/experimental.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Python/qsharp-core/qsharp/experimental.py b/src/Python/qsharp-core/qsharp/experimental.py index da1c4d1774..a8b2831b27 100644 --- a/src/Python/qsharp-core/qsharp/experimental.py +++ b/src/Python/qsharp-core/qsharp/experimental.py @@ -239,7 +239,7 @@ def _as_jobj(self): [ pr, [ - str(qsharp.Pauli[p] if isinstance(p, str) else qsharp.Pauli(p)) + (qsharp.Pauli[p] if isinstance(p, str) else qsharp.Pauli(p)).name for p in ops ] ] From fa37ae7d872dcab9fa3f00e73447a0c494bd4a93 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 9 Jun 2021 08:32:27 -0700 Subject: [PATCH 39/43] Update to latest build. --- src/Core/Core.csproj | 8 ++--- .../ExecutionPathTracer.csproj | 2 +- .../Mock.Chemistry/Mock.Chemistry.csproj | 4 +-- .../Mock.Standard/Mock.Standard.csproj | 4 +-- .../ProjectA.csproj | 2 +- .../ProjectB.csproj | 2 +- .../Workspace.ProjectReferences.csproj | 4 +-- src/Tool/appsettings.json | 32 +++++++++---------- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 9de7c5d273..c504527d2f 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -38,10 +38,10 @@ - - - - + + + + diff --git a/src/ExecutionPathTracer/ExecutionPathTracer.csproj b/src/ExecutionPathTracer/ExecutionPathTracer.csproj index 81bbc83e3b..601a67dbf5 100644 --- a/src/ExecutionPathTracer/ExecutionPathTracer.csproj +++ b/src/ExecutionPathTracer/ExecutionPathTracer.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj index 639feb7758..d80204f186 100644 --- a/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj +++ b/src/MockLibraries/Mock.Chemistry/Mock.Chemistry.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj index 639feb7758..d80204f186 100644 --- a/src/MockLibraries/Mock.Standard/Mock.Standard.csproj +++ b/src/MockLibraries/Mock.Standard/Mock.Standard.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,6 +6,6 @@ - + diff --git a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj index 4f697e9f15..d992114bd1 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectA/ProjectA.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj index a7bcc35634..831bef2cd2 100644 --- a/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj +++ b/src/Tests/Workspace.ProjectReferences.ProjectB/ProjectB.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 diff --git a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj index 2ec6f1dcc3..e736eff582 100644 --- a/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj +++ b/src/Tests/Workspace.ProjectReferences/Workspace.ProjectReferences.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,7 @@ - + diff --git a/src/Tool/appsettings.json b/src/Tool/appsettings.json index 668f71d759..cdbb71082f 100644 --- a/src/Tool/appsettings.json +++ b/src/Tool/appsettings.json @@ -6,26 +6,26 @@ }, "AllowedHosts": "*", "DefaultPackageVersions": [ - "Microsoft.Quantum.Compiler::0.17.210627739-alpha", + "Microsoft.Quantum.Compiler::0.17.210627752-alpha", - "Microsoft.Quantum.CSharpGeneration::0.17.210627739-alpha", - "Microsoft.Quantum.Development.Kit::0.17.210627739-alpha", - "Microsoft.Quantum.Simulators::0.17.210627739-alpha", - "Microsoft.Quantum.Xunit::0.17.210627739-alpha", + "Microsoft.Quantum.CSharpGeneration::0.17.210627752-alpha", + "Microsoft.Quantum.Development.Kit::0.17.210627752-alpha", + "Microsoft.Quantum.Simulators::0.17.210627752-alpha", + "Microsoft.Quantum.Xunit::0.17.210627752-alpha", - "Microsoft.Quantum.Standard::0.17.210627739-alpha", - "Microsoft.Quantum.Standard.Visualization::0.17.210627739-alpha", - "Microsoft.Quantum.Chemistry::0.17.210627739-alpha", - "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627739-alpha", - "Microsoft.Quantum.MachineLearning::0.17.210627739-alpha", - "Microsoft.Quantum.Numerics::0.17.210627739-alpha", + "Microsoft.Quantum.Standard::0.17.210627752-alpha", + "Microsoft.Quantum.Standard.Visualization::0.17.210627752-alpha", + "Microsoft.Quantum.Chemistry::0.17.210627752-alpha", + "Microsoft.Quantum.Chemistry.Jupyter::0.17.210627752-alpha", + "Microsoft.Quantum.MachineLearning::0.17.210627752-alpha", + "Microsoft.Quantum.Numerics::0.17.210627752-alpha", - "Microsoft.Quantum.Katas::0.17.210627739-alpha", + "Microsoft.Quantum.Katas::0.17.210627752-alpha", - "Microsoft.Quantum.Research::0.17.210627739-alpha", + "Microsoft.Quantum.Research::0.17.210627752-alpha", - "Microsoft.Quantum.Providers.IonQ::0.17.210627739-alpha", - "Microsoft.Quantum.Providers.Honeywell::0.17.210627739-alpha", - "Microsoft.Quantum.Providers.QCI::0.17.210627739-alpha" + "Microsoft.Quantum.Providers.IonQ::0.17.210627752-alpha", + "Microsoft.Quantum.Providers.Honeywell::0.17.210627752-alpha", + "Microsoft.Quantum.Providers.QCI::0.17.210627752-alpha" ] } From 2d4114e5716341ef657251002d491c84a74af9ed Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Wed, 9 Jun 2021 15:02:15 -0700 Subject: [PATCH 40/43] One more slight encoder fix. --- src/Jupyter/Visualization/OpenSystemsEncoders.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Jupyter/Visualization/OpenSystemsEncoders.cs b/src/Jupyter/Visualization/OpenSystemsEncoders.cs index 452742e934..ac5ddcbf98 100644 --- a/src/Jupyter/Visualization/OpenSystemsEncoders.cs +++ b/src/Jupyter/Visualization/OpenSystemsEncoders.cs @@ -145,7 +145,7 @@ public StabilizerStateToHtmlDisplayEncoder(IConfigurationSource config) .Range(nQubits, data.Shape[0] / 2) .Select( idxRow => - (data[idxRow, ~1] ? "-" : "") + + (data[idxRow, 2 * nQubits] == true ? "-" : "") + string.Join("", Enumerable.Range(0, nQubits) .Select(idxQubit => @@ -171,7 +171,7 @@ public StabilizerStateToHtmlDisplayEncoder(IConfigurationSource config) .Range(nQubits, data.Shape[0] / 2) .Select( idxRow => - (data[idxRow, ~1] ? "-" : "") + + (data[idxRow, 2 * nQubits] == true ? "-" : "") + string.Join("", Enumerable.Range(0, nQubits) .Select(idxQubit => From cc52fb091e1c7e9cdf83c498f369e7ab98ac3562 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 11 Jun 2021 13:38:57 -0700 Subject: [PATCH 41/43] Move IQ# build to latest version of Ubuntu. --- build/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/ci.yml b/build/ci.yml index 498141e489..0f11ad451a 100644 --- a/build/ci.yml +++ b/build/ci.yml @@ -24,6 +24,8 @@ variables: jobs: - job: "iqsharp" + pool: + vmImage: 'ubuntu-latest' steps: - template: steps.yml - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 From a3879359ca0f0e5fcea6765b6d0f471808ce99aa Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Fri, 11 Jun 2021 19:08:02 -0700 Subject: [PATCH 42/43] Trivial change to invalidate builds. --- src/Python/qsharp-core/qsharp/clients/iqsharp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Python/qsharp-core/qsharp/clients/iqsharp.py b/src/Python/qsharp-core/qsharp/clients/iqsharp.py index e4d05914bb..8d4fde9aaa 100644 --- a/src/Python/qsharp-core/qsharp/clients/iqsharp.py +++ b/src/Python/qsharp-core/qsharp/clients/iqsharp.py @@ -7,6 +7,7 @@ # Licensed under the MIT License. ## +## IMPORTS ## import subprocess import time From 6bec1c0459075f17329337f02a48f40c91dd1991 Mon Sep 17 00:00:00 2001 From: Christopher Granade Date: Mon, 14 Jun 2021 14:12:42 -0700 Subject: [PATCH 43/43] Use -any.whl to block Windows-specific wheels on Linux images. --- images/iqsharp-base/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/images/iqsharp-base/Dockerfile b/images/iqsharp-base/Dockerfile index 3eee9907b1..3466dfff6c 100644 --- a/images/iqsharp-base/Dockerfile +++ b/images/iqsharp-base/Dockerfile @@ -97,7 +97,9 @@ RUN mkdir -p ${HOME}/.nuget/NuGet && \ cat ${HOME}/.nuget/NuGet/NuGet.Config # Add Python and NuGet packages from the build context ADD nugets/*.nupkg ${LOCAL_PACKAGES}/nugets/ -ADD wheels/*.whl ${LOCAL_PACKAGES}/wheels/ +# When adding wheels, use *-any.whl to make sure that platform-specific wheels +# are not incorrectly added to the Docker image. +ADD wheels/*-any.whl ${LOCAL_PACKAGES}/wheels/ # Give the notebook user ownership over the packages and config copied from # the context. RUN chown ${USER} -R ${LOCAL_PACKAGES}/ && \