diff --git a/src/Simulation/Core/Argument.cs b/src/Simulation/Core/Argument.cs new file mode 100644 index 00000000000..b7ef2efbff5 --- /dev/null +++ b/src/Simulation/Core/Argument.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +namespace Microsoft.Quantum.Runtime +{ + /// + /// An argument to a QIR callable. + /// + public class Argument + { + /// + /// The name of the argument. + /// + public string Name { get; } + + /// + /// The value of the argument. + /// + public ArgumentValue Value { get; } + + /// + /// Creates a new argument. + /// + /// The name of the argument. + /// The value of the argument. + public Argument(string name, ArgumentValue value) => (this.Name, this.Value) = (name, value); + } +} diff --git a/src/Simulation/Core/ArgumentType.cs b/src/Simulation/Core/ArgumentType.cs new file mode 100644 index 00000000000..7dc2db55f22 --- /dev/null +++ b/src/Simulation/Core/ArgumentType.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +namespace Microsoft.Quantum.Runtime +{ + /// + /// The type of an argument to a QIR callable. + /// + public class ArgumentType + { + private ArgumentType() + { + } + + /// + /// The boolean type. + /// + public static ArgumentType Bool { get; } = new ArgumentType(); + + /// + /// The integer type. + /// + public static ArgumentType Int { get; } = new ArgumentType(); + + /// + /// The double-precision floating point type. + /// + public static ArgumentType Double { get; } = new ArgumentType(); + + /// + /// The Pauli operator type. + /// + public static ArgumentType Pauli { get; } = new ArgumentType(); + + /// + /// The range type. + /// + public static ArgumentType Range { get; } = new ArgumentType(); + + /// + /// The result type. + /// + public static ArgumentType Result { get; } = new ArgumentType(); + + /// + /// The string type. + /// + public static ArgumentType String { get; } = new ArgumentType(); + + /// + /// The array type. + /// + public class Array : ArgumentType + { + /// + /// The type of the array items. + /// + public ArgumentType Item { get; } + + /// + /// Creates a new array type. + /// + /// The type of the array items. + public Array(ArgumentType item) => this.Item = item; + + public override bool Equals(object obj) => obj is Array array && this.Item.Equals(array.Item); + + public override int GetHashCode() => this.Item.GetHashCode() + 1; + } + } +} diff --git a/src/Simulation/Core/ArgumentValue.cs b/src/Simulation/Core/ArgumentValue.cs new file mode 100644 index 00000000000..8f9c713b29b --- /dev/null +++ b/src/Simulation/Core/ArgumentValue.cs @@ -0,0 +1,185 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +using System.Collections.Immutable; +using System.Linq; +using Microsoft.Quantum.Simulation.Core; +using Core = Microsoft.Quantum.Simulation.Core; + +namespace Microsoft.Quantum.Runtime +{ + /// + /// The value of an argument to a QIR callable is a discriminated union of the argument types. + /// + public abstract class ArgumentValue + { + /// + /// The type of the argument. + /// + public abstract ArgumentType Type { get; } + + private ArgumentValue() + { + } + + /// + /// A boolean argument value. + /// + public class Bool : ArgumentValue + { + /// + /// The value of the argument. + /// + public bool Value { get; } + + public override ArgumentType Type => ArgumentType.Bool; + + /// + /// Creates a boolean argument value. + /// + /// The value of the argument. + public Bool(bool value) => this.Value = value; + } + + /// + /// An integer argument value. + /// + public class Int : ArgumentValue + { + /// + /// The value of the argument. + /// + public long Value { get; } + + public override ArgumentType Type => ArgumentType.Int; + + /// + /// Creates an integer argument value. + /// + /// The value of the argument. + public Int(long value) => this.Value = value; + } + + /// + /// A double-precision floating point argument value. + /// + public class Double : ArgumentValue + { + /// + /// The value of the argument. + /// + public double Value { get; } + + public override ArgumentType Type => ArgumentType.Double; + + /// + /// Creates a double-precision floating point argument value. + /// + /// The value of the argument. + public Double(double value) => this.Value = value; + } + + /// + /// A Pauli operator argument value. + /// + public class Pauli : ArgumentValue + { + /// + /// The value of the argument. + /// + public Core.Pauli Value { get; } + + public override ArgumentType Type => ArgumentType.Pauli; + + /// + /// Creates a Pauli operator argument value. + /// + /// The value of the argument. + public Pauli(Core.Pauli value) => this.Value = value; + } + + /// + /// A range argument value. + /// + public class Range : ArgumentValue + { + /// + /// The value of the argument. + /// + public QRange Value { get; } + + public override ArgumentType Type => ArgumentType.Range; + + /// + /// Creates a range argument value. + /// + /// The value of the argument. + public Range(QRange value) => this.Value = value; + } + + /// + /// A result argument value. + /// + public class Result : ArgumentValue + { + /// + /// The value of the argument. + /// + public Core.Result Value { get; } + + public override ArgumentType Type => ArgumentType.Result; + + /// + /// Creates a result argument value. + /// + /// The value of the argument. + public Result(Core.Result value) => this.Value = value; + } + + /// + /// A string argument value. + /// + public class String : ArgumentValue + { + /// + /// The value of the argument. + /// + public string Value { get; } + + public override ArgumentType Type => ArgumentType.String; + + /// + /// Creates a string argument value. + /// + /// The value of the argument. + public String(string value) => this.Value = value; + } + + /// + /// An array argument value where all values are of the same type. + /// + public class Array : ArgumentValue + { + /// + /// The values of the argument. + /// + public ImmutableArray Values { get; } + + public override ArgumentType Type { get; } + + private Array(ImmutableArray values, ArgumentType itemType) => + (this.Values, this.Type) = (values, new ArgumentType.Array(itemType)); + + /// + /// Tries to create an array argument value. + /// + /// The values of the argument. + /// The type of the values. + /// The array or null if not all values have the type . + public static Array? TryCreate(ImmutableArray values, ArgumentType itemType) => + values.All(value => value.Type.Equals(itemType)) ? new Array(values, itemType) : null; + } + } +} diff --git a/src/Simulation/Core/Microsoft.Quantum.Runtime.Core.csproj b/src/Simulation/Core/Microsoft.Quantum.Runtime.Core.csproj index b5169a63955..866adc91ba0 100644 --- a/src/Simulation/Core/Microsoft.Quantum.Runtime.Core.csproj +++ b/src/Simulation/Core/Microsoft.Quantum.Runtime.Core.csproj @@ -18,6 +18,7 @@ + diff --git a/src/Simulation/Core/Submitters/IAzureSubmitter.cs b/src/Simulation/Core/Submitters/IAzureSubmitter.cs new file mode 100644 index 00000000000..0fc11515b3f --- /dev/null +++ b/src/Simulation/Core/Submitters/IAzureSubmitter.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +namespace Microsoft.Quantum.Runtime +{ + /// + /// An interface for submitting quantum programs to Azure. + /// + public interface IAzureSubmitter + { + /// + /// The ID of the quantum machine provider. + /// + string ProviderId { get; } + + /// + /// The name of the target quantum machine. A provider may expose multiple targets that can be used to execute + /// programs. Users may select which target they would like to be used for execution. + /// + string Target { get; } + } +} diff --git a/src/Simulation/Core/Submitters/IQirSubmitter.cs b/src/Simulation/Core/Submitters/IQirSubmitter.cs new file mode 100644 index 00000000000..f18c171c6f0 --- /dev/null +++ b/src/Simulation/Core/Submitters/IQirSubmitter.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#nullable enable + +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace Microsoft.Quantum.Runtime +{ + /// + /// An interface for submitting QIR programs to Azure. + /// + public interface IQirSubmitter : IAzureSubmitter + { + /// + /// Submits a job to execute a QIR program without waiting for execution to complete. + /// + /// The QIR program as a byte stream. + /// The fully-qualified name of the entry point to execute. + /// The arguments to the entry point in the order in which they are declared. + /// The submitted job. + Task SubmitAsync(Stream qir, string entryPoint, IReadOnlyList arguments); + } +} diff --git a/src/Simulation/Core/Submitters/IQuantumMachine.cs b/src/Simulation/Core/Submitters/IQuantumMachine.cs index 0e7cc236692..361a6eea37a 100644 --- a/src/Simulation/Core/Submitters/IQuantumMachine.cs +++ b/src/Simulation/Core/Submitters/IQuantumMachine.cs @@ -7,28 +7,15 @@ namespace Microsoft.Quantum.Runtime { /// - /// Interface that a quantum machine must implement. + /// An interface for submitting Q# programs to Azure. /// - public interface IQuantumMachine + public interface IQuantumMachine : IAzureSubmitter { - /// /// Function that configures a job object before submission. /// public delegate void ConfigureJob(object job); - /// - /// Gets the ID of the quantum machine provider. - /// - string ProviderId { get; } - - /// - /// Gets the name of the target quantum machine. - /// A provider may expose multiple targets that can be used to execute programs. - /// Users may select which target they would like to be used for execution. - /// - string Target { get; } - /// /// Executes a Q# program. /// Submits a job to execute it and continuously checks whether it has been completed.