diff --git a/src/Jupyter/ChannelWithNewLines.cs b/src/Jupyter/ChannelWithNewLines.cs
index 0b602a04cb..d89d8b24a2 100644
--- a/src/Jupyter/ChannelWithNewLines.cs
+++ b/src/Jupyter/ChannelWithNewLines.cs
@@ -9,27 +9,72 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
///
- /// This is a Jupyter Core IChannel that wraps an existing IChannel and
+ /// This is a Jupyter Core IChannel that wraps an existing IChannel and
/// adds NewLine symbols (\\n)
/// to every message that gets logged to Stdout and Stderror.
///
public class ChannelWithNewLines : IChannel
{
+ ///
+ /// The existing channel that this channel wraps with new lines.
+ ///
public IChannel BaseChannel { get; }
+ ///
+ /// Constructs a new channel, given a base channel to be wrapped
+ /// with newlines.
+ ///
public ChannelWithNewLines(IChannel original)
{
BaseChannel = original;
}
+ ///
+ /// Formats a given message for display to stdout or stderr.
+ ///
+ /// The message to be formatted.
+ ///
+ /// , formatted with a trailing newline
+ /// (\n).
+ ///
public static string Format(string msg) => $"{msg}\n";
+ ///
+ /// Writes a given message to the base channel's standard output,
+ /// but with a trailing newline appended.
+ ///
+ /// The message to be written.
public void Stdout(string message) => BaseChannel?.Stdout(Format(message));
+ ///
+ /// Writes a given message to the base channel's standard error,
+ /// but with a trailing newline appended.
+ ///
+ /// The message to be written.
public void Stderr(string message) => BaseChannel?.Stderr(Format(message));
+ ///
+ /// Displays a given object using the base channel.
+ ///
+ /// The object to be displayed.
+ ///
+ /// Note that no newline is appended by this method, as the
+ /// displayable object need not be a string.
+ ///
public void Display(object displayable) => BaseChannel?.Display(displayable);
+ ///
+ /// Displays a given object using the base channel, allowing for
+ /// future updates.
+ ///
+ /// The object to be displayed.
+ ///
+ /// Note that no newline is appended by this method, as the
+ /// displayable object need not be a string.
+ ///
+ ///
+ /// An object that can be used to update the display in the future.
+ ///
public IUpdatableDisplay DisplayUpdatable(object displayable) => BaseChannel?.DisplayUpdatable(displayable);
}
}
diff --git a/src/Jupyter/ConfigurationSource.cs b/src/Jupyter/ConfigurationSource.cs
index 499de1bc95..6bb5c1fb63 100644
--- a/src/Jupyter/ConfigurationSource.cs
+++ b/src/Jupyter/ConfigurationSource.cs
@@ -13,10 +13,23 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// A service that controls configuration options, such as those set
+ /// by preferences, the %config magic command, and so forth.
+ ///
public interface IConfigurationSource
{
+ ///
+ /// A dictionary of configuration options available from this
+ /// source.
+ ///
IDictionary Configuration { get; }
+ ///
+ /// Persists the current configuration to disk such that a future
+ /// kernel session launched for the same notebook has the given
+ /// configuration.
+ ///
void Persist();
private T GetOptionOrDefault(string optionName, T defaultValue) =>
@@ -24,24 +37,52 @@ private T GetOptionOrDefault(string optionName, T defaultValue) =>
? token.ToObject() ?? defaultValue
: defaultValue;
+ ///
+ /// The labeling convention to be used when labeling computational
+ /// basis states (bit string, little-endian or big-endian).
+ ///
public BasisStateLabelingConvention BasisStateLabelingConvention =>
GetOptionOrDefault("dump.basisStateLabelingConvention", BasisStateLabelingConvention.LittleEndian);
+ ///
+ /// Whether small amplitudes should be truncated when dumping
+ /// states.
+ ///
public bool TruncateSmallAmplitudes =>
GetOptionOrDefault("dump.truncateSmallAmplitudes", false);
+ ///
+ /// The threshold for truncating measurement probabilities when
+ /// dumping states. Computational basis states whose measurement
+ /// probabilities (i.e: squared magnitudes) are below this threshold
+ /// are subject to truncation when
+ ///
+ /// is true.
+ ///
public double TruncationThreshold =>
GetOptionOrDefault("dump.truncationThreshold", 1e-10);
}
+ ///
+ /// An implementation of the
+ ///
+ /// service interface that loads and persists configuration values from
+ /// and to a local JSON file.
+ ///
public class ConfigurationSource : IConfigurationSource
{
+ ///
public IDictionary Configuration => _Configuration;
private readonly IDictionary _Configuration;
private string ConfigPath =>
Path.Join(Directory.GetCurrentDirectory(), ".iqsharp-config.json");
+ ///
+ /// Constructs a new configuration source, loading initial
+ /// configuration options from the file .iqsharp-config.json,
+ /// if that file exists.
+ ///
public ConfigurationSource(bool skipLoading = false)
{
// Try loading configuration from a JSON file in the current working
@@ -65,6 +106,10 @@ public ConfigurationSource(bool skipLoading = false)
}
}
+ ///
+ /// Persists the current configuration to
+ /// .iqsharp-config.json.
+ ///
public void Persist()
{
// Try writing the configuration back to JSON.
diff --git a/src/Jupyter/Extensions.cs b/src/Jupyter/Extensions.cs
index 068bae1636..7ad662401c 100644
--- a/src/Jupyter/Extensions.cs
+++ b/src/Jupyter/Extensions.cs
@@ -14,6 +14,9 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// Extension methods to be used with various IQ# and Jupyter objects.
+ ///
public static class Extensions
{
@@ -24,6 +27,10 @@ public static class Extensions
public static ChannelWithNewLines WithNewLines(this IChannel original) =>
(original is ChannelWithNewLines ch) ? ch : new ChannelWithNewLines(original);
+ ///
+ /// Adds services required for the IQ# kernel to a given service
+ /// collection.
+ ///
public static void AddIQSharpKernel(this IServiceCollection services)
{
services.AddSingleton();
@@ -31,6 +38,11 @@ public static void AddIQSharpKernel(this IServiceCollection services)
services.AddSingleton();
}
+ ///
+ /// Given a configuration source, applies an action if that
+ /// configuration source defines a value for a particular
+ /// configuration key.
+ ///
internal static IConfigurationSource ApplyConfiguration(
this IConfigurationSource configurationSource,
string keyName, Action action
@@ -52,6 +64,15 @@ internal static IConfigurationSource ApplyConfiguration(
(1L << 10, "KiB")
}.ToImmutableList();
+ ///
+ /// Given a number of bytes, formats that number as a human
+ /// readable string by appending unit suffixes (i.e.: indicating
+ /// kilobytes, megabytes, etc.).
+ ///
+ /// A number of bytes to be formatted.
+ ///
+ /// The number of bytes formatted as a human-readable string.
+ ///
public static string ToHumanReadableBytes(this long nBytes)
{
foreach (var (scale, suffix) in byteSuffixes)
@@ -66,11 +87,42 @@ public static string ToHumanReadableBytes(this long nBytes)
return $"{nBytes} B";
}
+ ///
+ /// Adds functionality to a given quantum simulator to display
+ /// diagnostic output with rich Jupyter formatting.
+ ///
+ ///
+ /// The simulator to be augmented with Jupyter display
+ /// functionality.
+ ///
+ ///
+ /// The Jupyter display channel to be used to display diagnostic
+ /// output.
+ ///
+ ///
+ /// A source of configuration options to be used to set display
+ /// preferences. Typically, this will be provided by the service
+ /// provider configured when an execution engine is constructed.
+ ///
+ ///
+ /// The value of .
+ ///
public static QuantumSimulator WithJupyterDisplay(this QuantumSimulator simulator, IChannel channel, IConfigurationSource configurationSource)
{
+ // First, we disable console-based logging so as to not
+ // duplicate messages.
simulator.DisableLogToConsole();
+ // Next, we attach the display channel's standard output handling
+ // to the log event.
simulator.OnLog += channel.Stdout;
+ // Next, we register the generic version of the DumpMachine callable
+ // as an ICallable with the simulator. Below, we'll provide our
+ // implementation of DumpMachine with the channel and configuration
+ // source we got as arguments. At the moment, there's no direct
+ // way to do this when registering an implementation, so we instead
+ // get an instance of the newly registered callable and set its
+ // properties accordingly.
simulator.Register(
typeof(Diagnostics.DumpMachine<>), typeof(JupyterDumpMachine<>),
signature: typeof(ICallable)
@@ -84,6 +136,8 @@ public static QuantumSimulator WithJupyterDisplay(this QuantumSimulator simulato
((JupyterDumpMachine)concreteOp).Channel = channel;
((JupyterDumpMachine)concreteOp).ConfigurationSource = configurationSource;
+ // Next, we repeat the whole process for DumpRegister instead of
+ // DumpMachine.
simulator.Register(
typeof(Diagnostics.DumpRegister<>), typeof(JupyterDumpRegister<>),
signature: typeof(ICallable)
diff --git a/src/Jupyter/Jupyter.csproj b/src/Jupyter/Jupyter.csproj
index 8e38e21098..e506bb1607 100644
--- a/src/Jupyter/Jupyter.csproj
+++ b/src/Jupyter/Jupyter.csproj
@@ -5,6 +5,7 @@
x64
Microsoft.Quantum.IQSharp.Jupyter
Microsoft.Quantum.IQSharp.Jupyter
+ true
diff --git a/src/Jupyter/KernelProperties.cs b/src/Jupyter/KernelProperties.cs
index d29dd350a4..8777bcf7d0 100644
--- a/src/Jupyter/KernelProperties.cs
+++ b/src/Jupyter/KernelProperties.cs
@@ -10,6 +10,10 @@ namespace Microsoft.Quantum.IQSharp.Jupyter
///
public static class Constants
{
+ ///
+ /// The properties for this kernel (e.g. versions, language name,
+ /// etc.).
+ ///
public static readonly KernelProperties IQSharpKernelProperties = new KernelProperties
{
FriendlyName = "Q#",
@@ -18,7 +22,7 @@ public static class Constants
DisplayName = "Q#",
LanguageName = "qsharp",
- LanguageVersion = "0.4",
+ LanguageVersion = "0.10",
LanguageMimeType = "text/x-qsharp",
LanguageFileExtension = ".qs",
diff --git a/src/Jupyter/Magic/AbstractMagic.cs b/src/Jupyter/Magic/AbstractMagic.cs
index e8020842f7..999d8b4824 100644
--- a/src/Jupyter/Magic/AbstractMagic.cs
+++ b/src/Jupyter/Magic/AbstractMagic.cs
@@ -10,8 +10,14 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// Abstract base class for IQ# magic symbols.
+ ///
public abstract class AbstractMagic : MagicSymbol
{
+ ///
+ /// Constructs a new magic symbol given its name and documentation.
+ ///
public AbstractMagic(string keyword, Documentation docs)
{
this.Name = $"%{keyword}";
@@ -21,7 +27,14 @@ public AbstractMagic(string keyword, Documentation docs)
this.Execute = SafeExecute(this.Run);
}
- public Func SafeExecute(Func magic) =>
+ ///
+ /// Given a function representing the execution of a magic command,
+ /// returns a new function that executes
+ /// and catches any exceptions that occur during execution. The
+ /// returned execution function displays the given exceptions to its
+ /// display channel.
+ ///
+ public Func SafeExecute(Func magic) =>
(input, channel) =>
{
channel = channel.WithNewLines();
@@ -47,6 +60,10 @@ public Func SafeExecute(Func
+ /// Parses the input to a magic command, interpreting the input as
+ /// a name followed by a JSON-serialized dictionary.
+ ///
public static (string, Dictionary) ParseInput(string input)
{
if (input == null) return (string.Empty, new Dictionary { });
@@ -61,6 +78,9 @@ public static (string, Dictionary) ParseInput(string input)
return (name, args);
}
+ ///
+ /// A method to be run when the magic command is executed.
+ ///
public abstract ExecutionResult Run(string input, IChannel channel);
}
}
diff --git a/src/Jupyter/Magic/ConfigMagic.cs b/src/Jupyter/Magic/ConfigMagic.cs
index 900d87295d..7dd95e7337 100644
--- a/src/Jupyter/Magic/ConfigMagic.cs
+++ b/src/Jupyter/Magic/ConfigMagic.cs
@@ -13,8 +13,15 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// A magic command that sets or queries configuration options.
+ ///
public class ConfigMagic : AbstractMagic
{
+ ///
+ /// Constructs a magic command that sets or queries configuration
+ /// options using a given configuration source.
+ ///
public ConfigMagic(IConfigurationSource configurationSource) : base(
"config",
new Documentation {
@@ -24,8 +31,14 @@ public ConfigMagic(IConfigurationSource configurationSource) : base(
this.ConfigurationSource = configurationSource;
}
+ ///
+ /// The configuration source which this magic command queries or
+ /// sets configuration options in.
+ ///
public IConfigurationSource ConfigurationSource { get; }
+
+ ///
public override ExecutionResult Run(string? input, IChannel channel)
{
// If we didn't get any input, treat it as a query.
diff --git a/src/Jupyter/Magic/EstimateMagic.cs b/src/Jupyter/Magic/EstimateMagic.cs
index d49b1ba10b..ae8e2c668b 100644
--- a/src/Jupyter/Magic/EstimateMagic.cs
+++ b/src/Jupyter/Magic/EstimateMagic.cs
@@ -12,23 +12,43 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// A magic command that performs resource estimation on functions and
+ /// operations.
+ ///
public class EstimateMagic : AbstractMagic
{
+ ///
+ /// Given a symbol resolver that can be used to locate operations,
+ /// constructs a new magic command that performs resource estimation
+ /// on resolved operations.
+ ///
public EstimateMagic(ISymbolResolver resolver) : base(
"estimate",
- new Documentation {
- Summary = "Runs a given function or operation on the QuantumSimulator target machine"
+ new Documentation
+ {
+ Summary = "Runs a given function or operation on the ResourcesEstimator target machine."
})
{
this.SymbolResolver = resolver;
}
+ ///
+ /// The symbol resolver that this magic command uses to locate
+ /// operations.
+ ///
public ISymbolResolver SymbolResolver { get; }
+ ///
public override ExecutionResult Run(string input, IChannel channel) =>
RunAsync(input, channel).Result;
+ ///
+ /// Given an input representing the name of an operation and a JSON
+ /// serialization of its inputs, returns a task that can be awaited
+ /// on for resource estimates from running that operation.
+ ///
public async Task RunAsync(string input, IChannel channel)
{
var (name, args) = ParseInput(input);
diff --git a/src/Jupyter/Magic/PackageMagic.cs b/src/Jupyter/Magic/PackageMagic.cs
index 2fb53087c6..4fad99d1ee 100644
--- a/src/Jupyter/Magic/PackageMagic.cs
+++ b/src/Jupyter/Magic/PackageMagic.cs
@@ -10,8 +10,16 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// A magic command that can be used to add new NuGet packages to the
+ /// current IQ# session.
+ ///
public class PackageMagic : AbstractMagic
{
+ ///
+ /// Constructs a new magic command that adds package references to
+ /// a given references collection.
+ ///
public PackageMagic(IReferences references) : base(
"package",
new Documentation {
@@ -21,8 +29,13 @@ public PackageMagic(IReferences references) : base(
this.References = references;
}
+ ///
+ /// The references collection that this magic command adds package
+ /// references to.
+ ///
public IReferences References { get; }
+ ///
public override ExecutionResult Run(string input, IChannel channel)
{
var (name, _) = ParseInput(input);
@@ -49,6 +62,11 @@ public override ExecutionResult Run(string input, IChannel channel)
return task.Result;
}
+ ///
+ /// Adds a package given a string representing its name and returns
+ /// a task that can be awaited on for the completion of the package
+ /// download.
+ ///
public async Task RunAsync(string name, IChannel channel, Action statusCallback)
{
if (!string.IsNullOrWhiteSpace(name))
diff --git a/src/Jupyter/Magic/PerformanceMagic.cs b/src/Jupyter/Magic/PerformanceMagic.cs
index 75bfd101dc..85320366aa 100644
--- a/src/Jupyter/Magic/PerformanceMagic.cs
+++ b/src/Jupyter/Magic/PerformanceMagic.cs
@@ -14,8 +14,15 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// A magic command that reports various performance metrics to the
+ /// user.
+ ///
public class PerformanceMagic : AbstractMagic
{
+ ///
+ /// Constructs a new performance command.
+ ///
public PerformanceMagic() : base(
"performance",
new Documentation {
@@ -24,6 +31,7 @@ public PerformanceMagic() : base(
{
}
+ ///
public override ExecutionResult Run(string? input, IChannel channel)
{
var currentProcess = Process.GetCurrentProcess();
diff --git a/src/Jupyter/Magic/Simulate.cs b/src/Jupyter/Magic/Simulate.cs
index 1584848e4e..495dcadce6 100644
--- a/src/Jupyter/Magic/Simulate.cs
+++ b/src/Jupyter/Magic/Simulate.cs
@@ -11,8 +11,17 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// A magic command that can be used to simulate operations and functions
+ /// on a full-state quantum simulator.
+ ///
public class SimulateMagic : AbstractMagic
{
+ ///
+ /// Constructs a new magic command given a resolver used to find
+ /// operations and functions, and a configuration source used to set
+ /// configuration options.
+ ///
public SimulateMagic(ISymbolResolver resolver, IConfigurationSource configurationSource) : base(
"simulate",
new Documentation {
@@ -23,12 +32,26 @@ public SimulateMagic(ISymbolResolver resolver, IConfigurationSource configuratio
this.ConfigurationSource = configurationSource;
}
+ ///
+ /// 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 (name, args) = ParseInput(input);
diff --git a/src/Jupyter/Magic/ToffoliMagic.cs b/src/Jupyter/Magic/ToffoliMagic.cs
index 8cd7285432..b63ec1cb02 100644
--- a/src/Jupyter/Magic/ToffoliMagic.cs
+++ b/src/Jupyter/Magic/ToffoliMagic.cs
@@ -32,6 +32,7 @@ public ToffoliMagic(ISymbolResolver resolver) : base(
///
public ISymbolResolver SymbolResolver { get; }
+ ///
public override ExecutionResult Run(string input, IChannel channel) =>
RunAsync(input, channel).Result;
diff --git a/src/Jupyter/Magic/WhoMagic.cs b/src/Jupyter/Magic/WhoMagic.cs
index 3cd3ef2844..d8c4e9ed23 100644
--- a/src/Jupyter/Magic/WhoMagic.cs
+++ b/src/Jupyter/Magic/WhoMagic.cs
@@ -9,19 +9,32 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// A magic command that can be used to query the functions and operations
+ /// defined within an IQ# session.
+ ///
public class WhoMagic : AbstractMagic
{
+ ///
+ /// Given a given snippets collection, constructs a new magic command
+ /// that queries callables defined in that snippets collection.
+ ///
public WhoMagic(ISnippets snippets) : base(
- "who",
- new Documentation {
+ "who",
+ new Documentation
+ {
Summary = "Provides actions related to the current workspace."
})
{
this.Snippets = snippets;
}
+ ///
+ /// The snippets collection queried by this magic command.
+ ///
public ISnippets Snippets { get; }
+ ///
public override ExecutionResult Run(string input, IChannel channel) =>
Snippets.Operations
.Select(op => op.FullName)
diff --git a/src/Jupyter/Magic/WorkspaceMagic.cs b/src/Jupyter/Magic/WorkspaceMagic.cs
index 4735c4eaf2..190605540c 100644
--- a/src/Jupyter/Magic/WorkspaceMagic.cs
+++ b/src/Jupyter/Magic/WorkspaceMagic.cs
@@ -9,8 +9,15 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// A magic symbol that provides access to a given workspace.
+ ///
public class WorkspaceMagic : AbstractMagic
{
+ ///
+ /// Given a workspace, constructs a new magic symbol to control
+ /// that workspace.
+ ///
public WorkspaceMagic(IWorkspace workspace) : base(
"workspace",
new Documentation {
@@ -20,10 +27,13 @@ public WorkspaceMagic(IWorkspace workspace) : base(
this.Workspace = workspace;
}
+ ///
+ /// The workspace controlled by this magic symbol.
+ ///
public IWorkspace Workspace { get; }
///
- /// Performs checks to verify if the Workspace is avaialble and in a success (no errors) state.
+ /// Performs checks to verify if the Workspace is available and in a success (no errors) state.
/// The method throws Exceptions if it finds it is not ready to execute.
///
public void CheckIfReady()
@@ -38,6 +48,7 @@ public void CheckIfReady()
}
}
+ ///
public override ExecutionResult Run(string input, IChannel channel)
{
var (command, _) = ParseInput(input);
diff --git a/src/Jupyter/MagicResolver.cs b/src/Jupyter/MagicResolver.cs
index d1e78613e1..7d30e7d0a4 100644
--- a/src/Jupyter/MagicResolver.cs
+++ b/src/Jupyter/MagicResolver.cs
@@ -28,6 +28,11 @@ public class MagicSymbolResolver : ISymbolResolver
private IReferences references;
private ILogger logger;
+ ///
+ /// Constructs a new magic symbol resolver using the provided
+ /// services to search assembly references for subclasses of
+ /// .
+ ///
public MagicSymbolResolver(IServiceProvider services, ILogger logger)
{
this.cache = new Dictionary();
diff --git a/src/Jupyter/SymbolEncoders.cs b/src/Jupyter/SymbolEncoders.cs
index 7688b827a7..7fecf52adf 100644
--- a/src/Jupyter/SymbolEncoders.cs
+++ b/src/Jupyter/SymbolEncoders.cs
@@ -13,8 +13,13 @@ namespace Microsoft.Quantum.IQSharp.Jupyter
///
public class IQSharpSymbolToTextResultEncoder : IResultEncoder
{
+ ///
public string MimeType => MimeTypes.PlainText;
+ ///
+ /// Checks if a displayable object is an IQ# symbol, and if so,
+ /// returns an encoding of that symbol into plain text.
+ ///
public EncodedData? Encode(object displayable)
{
if (displayable is IQSharpSymbol symbol)
@@ -33,8 +38,13 @@ public class IQSharpSymbolToTextResultEncoder : IResultEncoder
///
public class IQSharpSymbolToHtmlResultEncoder : IResultEncoder
{
+ ///
public string MimeType => MimeTypes.Html;
+ ///
+ /// Checks if a displayable object is an IQ# symbol, and if so,
+ /// returns an encoding of that symbol into HTML.
+ ///
public EncodedData? Encode(object displayable)
{
if (displayable is IQSharpSymbol symbol)
diff --git a/src/Jupyter/SymbolResolver.cs b/src/Jupyter/SymbolResolver.cs
index 7e85a111d5..abbac63984 100644
--- a/src/Jupyter/SymbolResolver.cs
+++ b/src/Jupyter/SymbolResolver.cs
@@ -20,25 +20,44 @@ namespace Microsoft.Quantum.IQSharp.Jupyter
[JsonObject(MemberSerialization.OptIn)]
public class IQSharpSymbol : ISymbol
{
+ ///
+ /// The information provided by the compiler about the operation
+ /// represented by this symbol.
+ ///
[JsonIgnore]
public OperationInfo Operation { get; }
+ ///
+ /// The name of the operation represented by this symbol.
+ ///
[JsonProperty("name")]
- public string Name =>
- Operation.FullName;
+ public string Name => Operation.FullName;
// TODO: serialize as stringenum.
+ ///
[JsonProperty("kind")]
public SymbolKind Kind { get; private set; }
+ ///
+ /// The source file in which the operation represented by this
+ /// symbol was defined.
+ ///
[JsonProperty("source")]
public string Source => Operation.Header.SourceFile.Value;
+ ///
+ /// The documentation for this symbol, as provided by its API
+ /// documentation comments.
+ ///
[JsonProperty("documentation")]
public string Documentation => String.Join("\n", Operation.Header.Documentation);
// TODO: expose documentation here.
+ ///
+ /// Constructs a new symbol given information about an operation
+ /// as provided by the Q# compiler.
+ ///
public IQSharpSymbol(OperationInfo op)
{
if (op == null) { throw new ArgumentNullException(nameof(op)); }
@@ -59,8 +78,8 @@ public class SymbolResolver : ISymbolResolver
/// Constructs a new resolver that looks for symbols in a given
/// collection of snippets.
///
- ///
- /// The collection of snippets to be used when resolving symbols.
+ ///
+ /// An object to be used to resolve operation names to symbols.
///
public SymbolResolver(IOperationResolver opsResolver)
{
diff --git a/src/Jupyter/Visualization/DataTableEncoders.cs b/src/Jupyter/Visualization/DataTableEncoders.cs
index fad8bc5002..d20fc5ecff 100644
--- a/src/Jupyter/Visualization/DataTableEncoders.cs
+++ b/src/Jupyter/Visualization/DataTableEncoders.cs
@@ -29,22 +29,42 @@ internal static Table AsJupyterTable(this DataTable table) =>
};
}
+ ///
+ /// Encodes instances as HTML
+ /// tables.
+ ///
public class DataTableToHtmlEncoder : IResultEncoder
{
private static readonly IResultEncoder tableEncoder = new TableToHtmlDisplayEncoder();
+
+ ///
public string MimeType => MimeTypes.Html;
+ ///
+ /// Checks if a displayable object represents a data table, and if
+ /// so, returns an encoding into an HTML table.
+ ///
public EncodedData? Encode(object displayable) =>
displayable is DataTable table
? tableEncoder.Encode(table.AsJupyterTable())
: null;
}
+ ///
+ /// Encodes instances as plain-text
+ /// tables.
+ ///
public class DataTableToTextEncoder : IResultEncoder
{
private static readonly IResultEncoder tableEncoder = new TableToTextDisplayEncoder();
+
+ ///
public string MimeType => MimeTypes.PlainText;
+ ///
+ /// Checks if a displayable object represents a data table, and if
+ /// so, returns an encoding into a plain-text table.
+ ///
public EncodedData? Encode(object displayable) =>
displayable is DataTable table
? tableEncoder.Encode(table.AsJupyterTable())
diff --git a/src/Jupyter/Visualization/StateDisplayEncoders.cs b/src/Jupyter/Visualization/StateDisplayEncoders.cs
index 776babbffe..29838273c2 100644
--- a/src/Jupyter/Visualization/StateDisplayEncoders.cs
+++ b/src/Jupyter/Visualization/StateDisplayEncoders.cs
@@ -15,14 +15,47 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// The convention to be used in labeling computational basis states
+ /// given their representations as strings of classical bits.
+ ///
[JsonConverter(typeof(StringEnumConverter))]
public enum BasisStateLabelingConvention
{
+ ///
+ /// Label computational states directly by their bit strings.
+ ///
+ ///
+ /// Following this convention, the state |0⟩ ⊗ |1⟩ ⊗ |1⟩ is labeled
+ /// by |011⟩.
+ ///
Bitstring,
+
+ ///
+ /// Label computational states directly by interpreting their bit
+ /// strings as little-endian encoded integers.
+ ///
+ ///
+ /// Following this convention, the state |0⟩ ⊗ |1⟩ ⊗ |1⟩ is labeled
+ /// by |6⟩.
+ ///
LittleEndian,
+
+ ///
+ /// Label computational states directly by interpreting their bit
+ /// strings as big-endian encoded integers.
+ ///
+ ///
+ /// Following this convention, the state |0⟩ ⊗ |1⟩ ⊗ |1⟩ is labeled
+ /// by |3⟩.
+ ///
BigEndian
}
+ ///
+ /// Represents a quantum state vector and all metadata needed to display
+ /// that state vector.
+ ///
public class DisplayableState
{
private static readonly IComparer ToIntComparer =
@@ -32,16 +65,29 @@ public class DisplayableState
)
);
+ ///
+ /// The indexes of each qubit on which this state is defined, or
+ /// null if these indexes are not known.
+ ///
public IEnumerable? QubitIds { get; set; }
+
+ ///
+ /// The number of qubits on which this state is defined.
+ ///
public int NQubits { get; set; }
-
+
///
/// These amplitudes represent the computational basis states
- /// labeled in little-endian order, as per the behavior of
+ /// labeled in little-endian order, as per the behavior of
/// .
///
public Complex[]? Amplitudes { get; set; }
+ ///
+ /// An enumerable source of the significant amplitudes of this state
+ /// vector and their labels, where significance and labels are
+ /// defined by the values loaded from .
+ ///
public IEnumerable<(Complex, string)> SignificantAmplitudes(
IConfigurationSource configurationSource
) => SignificantAmplitudes(
@@ -50,6 +96,21 @@ IConfigurationSource configurationSource
configurationSource.TruncationThreshold
);
+ ///
+ /// An enumerable source of the significant amplitudes of this state
+ /// vector and their labels.
+ ///
+ ///
+ /// The convention to be used in labeling each computational basis state.
+ ///
+ ///
+ /// Whether to truncate small amplitudes.
+ ///
+ ///
+ /// If is true,
+ /// then amplitudes whose absolute value squared are below this
+ /// threshold are suppressed.
+ ///
public IEnumerable<(Complex, string)> SignificantAmplitudes(
BasisStateLabelingConvention convention,
bool truncateSmallAmplitudes, double truncationThreshold
@@ -77,6 +138,11 @@ IConfigurationSource configurationSource
}
);
+ ///
+ /// Using the given labeling convention, returns the label for a
+ /// computational basis state described by its bit string as encoded
+ /// into an integer index in the little-endian encoding.
+ ///
public string BasisStateLabel(
BasisStateLabelingConvention convention, int index
) => convention switch
@@ -104,16 +170,30 @@ public string BasisStateLabel(
}
+ ///
+ /// A result encoder that displays quantum state vectors as HTML tables.
+ ///
public class StateVectorToHtmlResultEncoder : IResultEncoder
{
private const double TWO_PI = 2.0 * System.Math.PI;
+
+ ///
public string MimeType => MimeTypes.Html;
private IConfigurationSource ConfigurationSource;
+
+ ///
+ /// Constructs a new result encoder using configuration settings
+ /// provided by a given configuration source.
+ ///
public StateVectorToHtmlResultEncoder(IConfigurationSource configurationSource)
{
ConfigurationSource = configurationSource;
}
+ ///
+ /// Checks if a given display object is a state vector, and if so,
+ /// returns its encoding into an HTML table.
+ ///
public EncodedData? Encode(object displayable)
{
string StyleForAngle(double angle) =>
@@ -188,15 +268,29 @@ string StyleForAngle(double angle) =>
}
}
+ ///
+ /// A result encoder that displays quantum state vectors as plain-text
+ /// tables.
+ ///
public class StateVectorToTextResultEncoder : IResultEncoder
{
+ ///
public string MimeType => MimeTypes.PlainText;
private IConfigurationSource ConfigurationSource;
+
+ ///
+ /// Constructs a new result encoder using configuration settings
+ /// provided by a given configuration source.
+ ///
public StateVectorToTextResultEncoder(IConfigurationSource configurationSource)
{
ConfigurationSource = configurationSource;
}
+ ///
+ /// Checks if a given display object is a state vector, and if so,
+ /// returns its encoding into a plain-text table.
+ ///
public EncodedData? Encode(object displayable)
{
if (displayable is DisplayableState vector)
diff --git a/src/Jupyter/Visualization/StateDisplayOperations.cs b/src/Jupyter/Visualization/StateDisplayOperations.cs
index e560340f8b..951a4056e6 100644
--- a/src/Jupyter/Visualization/StateDisplayOperations.cs
+++ b/src/Jupyter/Visualization/StateDisplayOperations.cs
@@ -14,18 +14,43 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// A state dumper that encodes dumped states into Jupyter-display
+ /// objects.
+ ///
public class JupyterDisplayDumper : QuantumSimulator.StateDumper
{
private readonly IChannel Channel;
private long _count = -1;
private Complex[]? _data = null;
+ ///
+ /// Whether small amplitudes should be truncated when dumping
+ /// states.
+ ///
public bool TruncateSmallAmplitudes { get; set; } = false;
+
+ ///
+ /// The threshold for truncating measurement probabilities when
+ /// dumping states. Computational basis states whose measurement
+ /// probabilities (i.e: squared magnitudes) are below this threshold
+ /// are subject to truncation when
+ ///
+ /// is true.
+ ///
public double TruncationThreshold { get; set; } = 1e-10;
- public BasisStateLabelingConvention BasisStateLabelingConvention { get; set; } = BasisStateLabelingConvention.Bitstring;
+ ///
+ /// The labeling convention to be used when labeling computational
+ /// basis states.
+ ///
+ public BasisStateLabelingConvention BasisStateLabelingConvention { get; set; } = BasisStateLabelingConvention.Bitstring;
+ ///
+ /// Sets the properties of this display dumper from a given
+ /// configuration source.
+ ///
public JupyterDisplayDumper Configure(IConfigurationSource configurationSource)
{
configurationSource
@@ -37,11 +62,19 @@ public JupyterDisplayDumper Configure(IConfigurationSource configurationSource)
return this;
}
+ ///
+ /// Constructs a new display dumper for a given simulator, using a
+ /// given Jupyter display channel to output dumped states.
+ ///
public JupyterDisplayDumper(QuantumSimulator sim, IChannel channel) : base(sim)
{
Channel = channel;
}
+ ///
+ /// Used by the simulator to provide states when dumping.
+ /// Not intended to be called directly.
+ ///
public override bool Callback(uint idx, double real, double img)
{
if (_data == null) throw new Exception("Expected data buffer to be initialized before callback, but it was null.");
@@ -49,6 +82,10 @@ public override bool Callback(uint idx, double real, double img)
return true;
}
+ ///
+ /// Dumps the state of a register of qubits as a Jupyter displayable
+ /// object.
+ ///
public override bool Dump(IQArray? qubits = null)
{
_count = qubits == null
@@ -84,17 +121,24 @@ internal static QVoid DumpToChannel(QuantumSimulator sim, IChannel channel, ICon
}
}
+ ///
+ /// An implementation of
+ /// that dumps the state of its target machine to a Jupyter-displayable
+ /// object.
+ ///
public class JupyterDumpMachine : Microsoft.Quantum.Diagnostics.DumpMachine
{
private QuantumSimulator Simulator { get; }
internal IConfigurationSource? ConfigurationSource = null;
internal IChannel? Channel = null;
+ ///
public JupyterDumpMachine(QuantumSimulator m) : base(m)
{
this.Simulator = m;
}
+ ///
public override Func Body => (location) =>
{
if (location == null) { throw new ArgumentNullException(nameof(location)); }
@@ -120,16 +164,24 @@ public JupyterDumpMachine(QuantumSimulator m) : base(m)
};
}
+ ///
+ /// An implementation of
+ /// that dumps the state of its target machine to a Jupyter-displayable
+ /// object.
+ ///
public class JupyterDumpRegister : Microsoft.Quantum.Diagnostics.DumpRegister
{
private QuantumSimulator Simulator { get; }
internal IConfigurationSource? ConfigurationSource = null;
internal IChannel? Channel = null;
+
+ ///
public JupyterDumpRegister(QuantumSimulator m) : base(m)
{
this.Simulator = m;
}
+ ///
public override Func<(T, IQArray), QVoid> Body => (input) =>
{
var (location, qubits) = input;
diff --git a/src/Jupyter/Visualization/TaskStatusEncoders.cs b/src/Jupyter/Visualization/TaskStatusEncoders.cs
index d022f16bf8..1a65466a46 100644
--- a/src/Jupyter/Visualization/TaskStatusEncoders.cs
+++ b/src/Jupyter/Visualization/TaskStatusEncoders.cs
@@ -9,11 +9,26 @@
namespace Microsoft.Quantum.IQSharp.Jupyter
{
+ ///
+ /// Represents the status of a task, including its description,
+ /// completion status, and possibly a subtask description.
+ ///
public class TaskStatus
{
+ ///
+ /// The last time at which the status was updated.
+ ///
public DateTime LastUpdated { get; private set; } = DateTime.Now;
+
+ ///
+ /// Whether the status represents a completed task.
+ ///
public bool IsCompleted { get; set; } = false;
private string _description = "";
+
+ ///
+ /// A description of the task represented by this object.
+ ///
public string Description
{
get => _description;
@@ -25,6 +40,13 @@ public string Description
}
private string? _subtask = null;
+
+ ///
+ /// A description of the current subtask for this task (e.g. if
+ /// the task represents downloading multiple files, which file is
+ /// currently being downloaded). If there is no applicable subtask,
+ /// this property should be null.
+ ///
public string? Subtask
{
get => _subtask;
@@ -35,6 +57,9 @@ public string? Subtask
}
}
+ ///
+ /// Constructs a new status given the description of a task.
+ ///
public TaskStatus(string description)
{
Description = description;
@@ -46,8 +71,15 @@ public TaskStatus(string description)
///
public class TaskStatusToTextEncoder : IResultEncoder
{
+ ///
+ /// The MIME type returned by this encoder.
+ ///
public string MimeType => MimeTypes.PlainText;
+ ///
+ /// Checks if a displayable object is a task status, and if so,
+ /// returns its encoding into plain text.
+ ///
public EncodedData? Encode(object displayable)
{
if (displayable is TaskStatus status)