diff --git a/src/AzureClient/AzureClient.cs b/src/AzureClient/AzureClient.cs index 4ec62ed001..27ebd616f1 100644 --- a/src/AzureClient/AzureClient.cs +++ b/src/AzureClient/AzureClient.cs @@ -173,7 +173,7 @@ public async Task GetConnectionStatusAsync(IChannel channel) return ValidExecutionTargets.ToExecutionResult(); } - private async Task SubmitOrExecuteJobAsync(IChannel channel, string operationName, Dictionary inputParameters, bool execute) + private async Task SubmitOrExecuteJobAsync(IChannel channel, AzureSubmissionContext submissionContext, bool execute) { if (ActiveWorkspace == null) { @@ -187,7 +187,7 @@ private async Task SubmitOrExecuteJobAsync(IChannel channel, st return AzureClientError.NoTarget.ToExecutionResult(); } - if (string.IsNullOrEmpty(operationName)) + if (string.IsNullOrEmpty(submissionContext.OperationName)) { var commandName = execute ? "%azure.execute" : "%azure.submit"; channel.Stderr($"Please pass a valid Q# operation name to {commandName}."); @@ -202,40 +202,42 @@ private async Task SubmitOrExecuteJobAsync(IChannel channel, st return AzureClientError.InvalidTarget.ToExecutionResult(); } - channel.Stdout($"Submitting {operationName} to target {ActiveTarget.TargetId}..."); + channel.Stdout($"Submitting {submissionContext.OperationName} to target {ActiveTarget.TargetId}..."); IEntryPoint? entryPoint = null; try { - entryPoint = EntryPointGenerator.Generate(operationName, ActiveTarget.TargetId); + entryPoint = EntryPointGenerator.Generate(submissionContext.OperationName, ActiveTarget.TargetId); } catch (UnsupportedOperationException e) { - channel.Stderr($"{operationName} is not a recognized Q# operation name."); + channel.Stderr($"{submissionContext.OperationName} is not a recognized Q# operation name."); return AzureClientError.UnrecognizedOperationName.ToExecutionResult(); } catch (CompilationErrorsException e) { - channel.Stderr($"The Q# operation {operationName} could not be compiled as an entry point for job execution."); + channel.Stderr($"The Q# operation {submissionContext.OperationName} could not be compiled as an entry point for job execution."); foreach (var message in e.Errors) channel.Stderr(message); return AzureClientError.InvalidEntryPoint.ToExecutionResult(); } try { - var job = await entryPoint.SubmitAsync(machine, inputParameters); - channel.Stdout($"Job {job.Id} submitted successfully."); + var job = await entryPoint.SubmitAsync(machine, submissionContext); + channel.Stdout($"Job successfully submitted for {submissionContext.Shots} shots."); + channel.Stdout($" Job name: {submissionContext.FriendlyName}"); + channel.Stdout($" Job ID: {job.Id}"); MostRecentJobId = job.Id; } catch (ArgumentException e) { - channel.Stderr($"Failed to parse all expected parameters for Q# operation {operationName}."); + channel.Stderr($"Failed to parse all expected parameters for Q# operation {submissionContext.OperationName}."); channel.Stderr(e.Message); return AzureClientError.JobSubmissionFailed.ToExecutionResult(); } catch (Exception e) { - channel.Stderr($"Failed to submit Q# operation {operationName} for execution."); + channel.Stderr($"Failed to submit Q# operation {submissionContext.OperationName} for execution."); channel.Stderr(e.InnerException?.Message ?? e.Message); return AzureClientError.JobSubmissionFailed.ToExecutionResult(); } @@ -245,18 +247,16 @@ private async Task SubmitOrExecuteJobAsync(IChannel channel, st return await GetJobStatusAsync(channel, MostRecentJobId); } - var timeoutInSeconds = 30; - channel.Stdout($"Waiting up to {timeoutInSeconds} seconds for Azure Quantum job to complete..."); + channel.Stdout($"Waiting up to {submissionContext.ExecutionTimeout} seconds for Azure Quantum job to complete..."); - using (var cts = new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(30))) + using (var cts = new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(submissionContext.ExecutionTimeout))) { CloudJob? cloudJob = null; do { // TODO: Once jupyter-core supports interrupt requests (https://github.com/microsoft/jupyter-core/issues/55), // handle Jupyter kernel interrupt here and break out of this loop - var pollingIntervalInSeconds = 5; - await Task.Delay(TimeSpan.FromSeconds(pollingIntervalInSeconds)); + await Task.Delay(TimeSpan.FromSeconds(submissionContext.ExecutionPollingInterval)); if (cts.IsCancellationRequested) break; cloudJob = await GetCloudJob(MostRecentJobId); channel.Stdout($"[{DateTime.Now.ToLongTimeString()}] Current job status: {cloudJob?.Status ?? "Unknown"}"); @@ -268,12 +268,12 @@ private async Task SubmitOrExecuteJobAsync(IChannel channel, st } /// - public async Task SubmitJobAsync(IChannel channel, string operationName, Dictionary inputParameters) => - await SubmitOrExecuteJobAsync(channel, operationName, inputParameters, execute: false); + public async Task SubmitJobAsync(IChannel channel, AzureSubmissionContext submissionContext) => + await SubmitOrExecuteJobAsync(channel, submissionContext, execute: false); /// - public async Task ExecuteJobAsync(IChannel channel, string operationName, Dictionary inputParameters) => - await SubmitOrExecuteJobAsync(channel, operationName, inputParameters, execute: true); + public async Task ExecuteJobAsync(IChannel channel, AzureSubmissionContext submissionContext) => + await SubmitOrExecuteJobAsync(channel, submissionContext, execute: true); /// public async Task GetActiveTargetAsync(IChannel channel) diff --git a/src/AzureClient/AzureSubmissionContext.cs b/src/AzureClient/AzureSubmissionContext.cs new file mode 100644 index 0000000000..bfe023e9fc --- /dev/null +++ b/src/AzureClient/AzureSubmissionContext.cs @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Quantum.IQSharp.Jupyter; +using Microsoft.Quantum.Runtime; + +namespace Microsoft.Quantum.IQSharp.AzureClient +{ + /// + /// Represents the configuration settings for a job submission to Azure Quantum. + /// + public sealed class AzureSubmissionContext : IQuantumMachineSubmissionContext + { + private static readonly int DefaultShots = 500; + private static readonly int DefaultExecutionTimeoutInSeconds = 30; + private static readonly int DefaultExecutionPollingIntervalInSeconds = 5; + + internal static readonly string ParameterNameOperationName = "__operationName__"; + internal static readonly string ParameterNameJobName = "jobName"; + internal static readonly string ParameterNameShots = "shots"; + internal static readonly string ParameterNameTimeout = "timeout"; + internal static readonly string ParameterNamePollingInterval = "poll"; + + /// + public string FriendlyName { get; set; } = string.Empty; + + /// + public int Shots { get; set; } = DefaultShots; + + /// + /// The Q# operation name to be executed as part of this job. + /// + public string OperationName { get; set; } = string.Empty; + + /// + /// The input parameters to be provided to the specified Q# operation. + /// + public Dictionary InputParameters { get; set; } = new Dictionary(); + + /// + /// The execution timeout for the job, expressed in seconds. + /// + /// + /// This setting only applies to %azure.execute. It is ignored for %azure.submit. + /// The timeout determines how long the IQ# kernel will wait for the job to complete; + /// the Azure Quantum job itself will continue to execute until it is completed. + /// + public int ExecutionTimeout { get; set; } = DefaultExecutionTimeoutInSeconds; + + /// + /// The polling interval, in seconds, to check for job status updates + /// while waiting for an Azure Quantum job to complete execution. + /// + /// + /// This setting only applies to %azure.execute. It is ignored for %azure.submit. + /// + public int ExecutionPollingInterval { get; set; } = DefaultExecutionPollingIntervalInSeconds; + + /// + /// Parses the input from a magic command into an object + /// suitable for job submission via . + /// + public static AzureSubmissionContext Parse(string inputCommand) + { + var inputParameters = AbstractMagic.ParseInputParameters(inputCommand, firstParameterInferredName: ParameterNameOperationName); + var operationName = inputParameters.DecodeParameter(ParameterNameOperationName); + var jobName = inputParameters.DecodeParameter(ParameterNameJobName, defaultValue: operationName); + var shots = inputParameters.DecodeParameter(ParameterNameShots, defaultValue: DefaultShots); + var timeout = inputParameters.DecodeParameter(ParameterNameTimeout, defaultValue: DefaultExecutionTimeoutInSeconds); + var pollingInterval = inputParameters.DecodeParameter(ParameterNamePollingInterval, defaultValue: DefaultExecutionPollingIntervalInSeconds); + + var decodedParameters = inputParameters.ToDictionary( + item => item.Key, + item => inputParameters.DecodeParameter(item.Key)); + + return new AzureSubmissionContext() + { + FriendlyName = jobName, + Shots = shots, + OperationName = operationName, + InputParameters = decodedParameters, + ExecutionTimeout = timeout, + ExecutionPollingInterval = pollingInterval, + }; + } + } +} diff --git a/src/AzureClient/EntryPoint/EntryPoint.cs b/src/AzureClient/EntryPoint/EntryPoint.cs index 407f29d0d5..17d10806ed 100644 --- a/src/AzureClient/EntryPoint/EntryPoint.cs +++ b/src/AzureClient/EntryPoint/EntryPoint.cs @@ -39,18 +39,18 @@ public EntryPoint(object entryPointInfo, Type inputType, Type outputType, Operat } /// - public Task SubmitAsync(IQuantumMachine machine, Dictionary inputParameters) + public Task SubmitAsync(IQuantumMachine machine, AzureSubmissionContext submissionContext) { var parameterTypes = new List(); var parameterValues = new List(); foreach (var parameter in OperationInfo.RoslynParameters) { - if (!inputParameters.ContainsKey(parameter.Name)) + if (!submissionContext.InputParameters.ContainsKey(parameter.Name)) { throw new ArgumentException($"Required parameter {parameter.Name} was not specified."); } - string rawParameterValue = inputParameters[parameter.Name]; + string rawParameterValue = submissionContext.InputParameters[parameter.Name]; object? parameterValue = null; try { @@ -73,17 +73,18 @@ public Task SubmitAsync(IQuantumMachine machine, Dictionary< }; // Find and invoke the method on IQuantumMachine that is declared as: - // Task SubmitAsync(EntryPointInfo info, TInput input) + // Task SubmitAsync(EntryPointInfo info, TInput input, SubmissionContext context) var submitMethod = typeof(IQuantumMachine) .GetMethods() .Single(method => method.Name == "SubmitAsync" && method.IsGenericMethodDefinition - && method.GetParameters().Length == 2 + && method.GetParameters().Length == 3 && method.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == EntryPointInfo.GetType().GetGenericTypeDefinition() - && method.GetParameters()[1].ParameterType.IsGenericMethodParameter) + && method.GetParameters()[1].ParameterType.IsGenericMethodParameter + && method.GetParameters()[2].ParameterType == typeof(IQuantumMachineSubmissionContext)) .MakeGenericMethod(new Type[] { InputType, OutputType }); - var submitParameters = new object[] { EntryPointInfo, entryPointInput }; + var submitParameters = new object[] { EntryPointInfo, entryPointInput, submissionContext }; return (Task)submitMethod.Invoke(machine, submitParameters); } } diff --git a/src/AzureClient/EntryPoint/IEntryPoint.cs b/src/AzureClient/EntryPoint/IEntryPoint.cs index 4cc6e063d7..aa3f78caa5 100644 --- a/src/AzureClient/EntryPoint/IEntryPoint.cs +++ b/src/AzureClient/EntryPoint/IEntryPoint.cs @@ -21,8 +21,8 @@ public interface IEntryPoint /// Submits the entry point for execution to Azure Quantum. /// /// The object representing the job submission target. - /// The provided input parameters to the entry point operation. + /// The object representing the submission context for the job. /// The details of the submitted job. - public Task SubmitAsync(IQuantumMachine machine, Dictionary inputParameters); + public Task SubmitAsync(IQuantumMachine machine, AzureSubmissionContext submissionContext); } } diff --git a/src/AzureClient/IAzureClient.cs b/src/AzureClient/IAzureClient.cs index 62937522c8..d6c67678ff 100644 --- a/src/AzureClient/IAzureClient.cs +++ b/src/AzureClient/IAzureClient.cs @@ -128,7 +128,7 @@ public Task ConnectAsync(IChannel channel, /// /// Details of the submitted job, or an error if submission failed. /// - public Task SubmitJobAsync(IChannel channel, string operationName, Dictionary inputParameters); + public Task SubmitJobAsync(IChannel channel, AzureSubmissionContext submissionContext); /// /// Executes the specified Q# operation as a job to the currently active target @@ -137,7 +137,7 @@ public Task ConnectAsync(IChannel channel, /// /// The result of the executed job, or an error if execution failed. /// - public Task ExecuteJobAsync(IChannel channel, string operationName, Dictionary inputParameters); + public Task ExecuteJobAsync(IChannel channel, AzureSubmissionContext submissionContext); /// /// Sets the specified target for job submission. diff --git a/src/AzureClient/Magic/ExecuteMagic.cs b/src/AzureClient/Magic/ExecuteMagic.cs index a5f317688d..6a3080d274 100644 --- a/src/AzureClient/Magic/ExecuteMagic.cs +++ b/src/AzureClient/Magic/ExecuteMagic.cs @@ -3,6 +3,7 @@ #nullable enable +using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Jupyter.Core; @@ -15,8 +16,6 @@ namespace Microsoft.Quantum.IQSharp.AzureClient /// public class ExecuteMagic : AzureClientMagicBase { - private const string ParameterNameOperationName = "operationName"; - /// /// Initializes a new instance of the class. /// @@ -59,16 +58,7 @@ The Azure Quantum workspace must previously have been initialized /// public override async Task RunAsync(string input, IChannel channel) { - var inputParameters = ParseInputParameters(input, firstParameterInferredName: ParameterNameOperationName); - var operationName = inputParameters.DecodeParameter(ParameterNameOperationName); - - var decodedParameters = new Dictionary(); - foreach (var key in inputParameters.Keys) - { - decodedParameters[key] = inputParameters.DecodeParameter(key); - } - - return await AzureClient.ExecuteJobAsync(channel, operationName, decodedParameters); + return await AzureClient.ExecuteJobAsync(channel, AzureSubmissionContext.Parse(input)); } } } \ No newline at end of file diff --git a/src/AzureClient/Magic/OutputMagic.cs b/src/AzureClient/Magic/OutputMagic.cs index f4b722f556..17ca257a46 100644 --- a/src/AzureClient/Magic/OutputMagic.cs +++ b/src/AzureClient/Magic/OutputMagic.cs @@ -17,7 +17,7 @@ namespace Microsoft.Quantum.IQSharp.AzureClient /// public class OutputMagic : AzureClientMagicBase { - private const string ParameterNameJobId = "jobId"; + private const string ParameterNameJobId = "id"; /// /// Initializes a new instance of the class. diff --git a/src/AzureClient/Magic/StatusMagic.cs b/src/AzureClient/Magic/StatusMagic.cs index e3ee13d092..e7eaa56d6c 100644 --- a/src/AzureClient/Magic/StatusMagic.cs +++ b/src/AzureClient/Magic/StatusMagic.cs @@ -17,7 +17,7 @@ namespace Microsoft.Quantum.IQSharp.AzureClient /// public class StatusMagic : AzureClientMagicBase { - private const string ParameterNameJobId = "jobId"; + private const string ParameterNameJobId = "id"; /// /// Initializes a new instance of the class. diff --git a/src/AzureClient/Magic/SubmitMagic.cs b/src/AzureClient/Magic/SubmitMagic.cs index cb646a9903..516646382e 100644 --- a/src/AzureClient/Magic/SubmitMagic.cs +++ b/src/AzureClient/Magic/SubmitMagic.cs @@ -15,8 +15,6 @@ namespace Microsoft.Quantum.IQSharp.AzureClient /// public class SubmitMagic : AzureClientMagicBase { - private const string ParameterNameOperationName = "operationName"; - /// /// Initializes a new instance of the class. /// @@ -56,16 +54,7 @@ The Azure Quantum workspace must previously have been initialized /// public override async Task RunAsync(string input, IChannel channel) { - var inputParameters = ParseInputParameters(input, firstParameterInferredName: ParameterNameOperationName); - var operationName = inputParameters.DecodeParameter(ParameterNameOperationName); - - var decodedParameters = new Dictionary(); - foreach (var key in inputParameters.Keys) - { - decodedParameters[key] = inputParameters.DecodeParameter(key); - } - - return await AzureClient.SubmitJobAsync(channel, operationName, decodedParameters); + return await AzureClient.SubmitJobAsync(channel, AzureSubmissionContext.Parse(input)); } } } \ No newline at end of file diff --git a/src/Jupyter/Extensions.cs b/src/Jupyter/Extensions.cs index b016d9c328..7b2c1bb9bf 100644 --- a/src/Jupyter/Extensions.cs +++ b/src/Jupyter/Extensions.cs @@ -187,7 +187,7 @@ public static T DecodeParameter(this Dictionary parameters, s { return defaultValue; } - return (T)(JsonConvert.DeserializeObject(parameterValue)) ?? defaultValue; + return (T)System.Convert.ChangeType(JsonConvert.DeserializeObject(parameterValue), typeof(T)) ?? defaultValue; } } } diff --git a/src/Jupyter/Magic/AbstractMagic.cs b/src/Jupyter/Magic/AbstractMagic.cs index 1b0cd24c3a..09a3df31b8 100644 --- a/src/Jupyter/Magic/AbstractMagic.cs +++ b/src/Jupyter/Magic/AbstractMagic.cs @@ -93,7 +93,7 @@ public static Dictionary JsonToDict(string input) => /// Dictionary with the names and values of the parameters, /// where the values of the Dictionary are JSON-serialized objects. /// - public Dictionary ParseInputParameters(string input, string firstParameterInferredName = "") + public static Dictionary ParseInputParameters(string input, string firstParameterInferredName = "") { Dictionary inputParameters = new Dictionary(); diff --git a/src/Kernel/Magic/EstimateMagic.cs b/src/Kernel/Magic/EstimateMagic.cs index 7e227003b7..54e58f81d0 100644 --- a/src/Kernel/Magic/EstimateMagic.cs +++ b/src/Kernel/Magic/EstimateMagic.cs @@ -19,6 +19,8 @@ namespace Microsoft.Quantum.IQSharp.Kernel /// public class EstimateMagic : AbstractMagic { + private const string ParameterNameOperationName = "__operationName__"; + /// /// Given a symbol resolver that can be used to locate operations, /// constructs a new magic command that performs resource estimation @@ -52,15 +54,16 @@ public override ExecutionResult Run(string input, IChannel channel) => /// public async Task RunAsync(string input, IChannel channel) { - var (name, args) = ParseInput(input); + var inputParameters = ParseInputParameters(input, firstParameterInferredName: ParameterNameOperationName); + var name = inputParameters.DecodeParameter(ParameterNameOperationName); var symbol = SymbolResolver.Resolve(name) as IQSharpSymbol; if (symbol == null) throw new InvalidOperationException($"Invalid operation name: {name}"); var qsim = new ResourcesEstimator().WithStackTraceDisplay(channel); qsim.DisableLogToConsole(); - await symbol.Operation.RunAsync(qsim, args); + await symbol.Operation.RunAsync(qsim, inputParameters); return qsim.Data.ToExecutionResult(); } diff --git a/src/Kernel/Magic/Simulate.cs b/src/Kernel/Magic/Simulate.cs index 2b94eb9b06..5e552541b8 100644 --- a/src/Kernel/Magic/Simulate.cs +++ b/src/Kernel/Magic/Simulate.cs @@ -18,8 +18,7 @@ namespace Microsoft.Quantum.IQSharp.Kernel /// public class SimulateMagic : AbstractMagic { - private const string - ParameterNameOperationName = "operationName"; + private const string ParameterNameOperationName = "__operationName__"; /// /// Constructs a new magic command given a resolver used to find diff --git a/src/Kernel/Magic/ToffoliMagic.cs b/src/Kernel/Magic/ToffoliMagic.cs index bb46a50e8f..48160c2bef 100644 --- a/src/Kernel/Magic/ToffoliMagic.cs +++ b/src/Kernel/Magic/ToffoliMagic.cs @@ -16,6 +16,8 @@ namespace Microsoft.Quantum.IQSharp.Kernel /// public class ToffoliMagic : AbstractMagic { + private const string ParameterNameOperationName = "__operationName__"; + /// /// Default constructor. /// @@ -43,8 +45,9 @@ public override ExecutionResult Run(string input, IChannel channel) => /// public async Task RunAsync(string input, IChannel channel) { - var (name, args) = ParseInput(input); + var inputParameters = ParseInputParameters(input, firstParameterInferredName: ParameterNameOperationName); + var name = inputParameters.DecodeParameter(ParameterNameOperationName); var symbol = SymbolResolver.Resolve(name) as IQSharpSymbol; if (symbol == null) throw new InvalidOperationException($"Invalid operation name: {name}"); @@ -52,7 +55,7 @@ public async Task RunAsync(string input, IChannel channel) qsim.DisableLogToConsole(); qsim.OnLog += channel.Stdout; - var value = await symbol.Operation.RunAsync(qsim, args); + var value = await symbol.Operation.RunAsync(qsim, inputParameters); return value.ToExecutionResult(); } diff --git a/src/Tests/AzureClientEntryPointTests.cs b/src/Tests/AzureClientEntryPointTests.cs index 3aba6eb27a..48d0416c61 100644 --- a/src/Tests/AzureClientEntryPointTests.cs +++ b/src/Tests/AzureClientEntryPointTests.cs @@ -42,7 +42,9 @@ public async Task FromSnippet() var entryPoint = entryPointGenerator.Generate("HelloQ", null); Assert.IsNotNull(entryPoint); - var job = await entryPoint.SubmitAsync(new MockQuantumMachine(), new Dictionary()); + var job = await entryPoint.SubmitAsync( + new MockQuantumMachine(), + new AzureSubmissionContext()); Assert.IsNotNull(job); } @@ -61,7 +63,9 @@ public async Task FromWorkspace() var entryPoint = entryPointGenerator.Generate("Tests.qss.HelloAgain", null); Assert.IsNotNull(entryPoint); - var job = await entryPoint.SubmitAsync(new MockQuantumMachine(), new Dictionary() { { "count", "2" }, { "name", "test" } } ); + var job = await entryPoint.SubmitAsync( + new MockQuantumMachine(), + new AzureSubmissionContext() { InputParameters = new Dictionary() { ["count"] = "2", ["name"] = "test" } }); Assert.IsNotNull(job); } @@ -73,7 +77,9 @@ public async Task FromWorkspaceMissingArgument() Assert.IsNotNull(entryPoint); Assert.ThrowsException(() => - entryPoint.SubmitAsync(new MockQuantumMachine(), new Dictionary() { { "count", "2" } })); + entryPoint.SubmitAsync( + new MockQuantumMachine(), + new AzureSubmissionContext() { InputParameters = new Dictionary() { ["count"] = "2" } })); } [TestMethod] @@ -84,7 +90,9 @@ public async Task FromWorkspaceIncorrectArgumentType() Assert.IsNotNull(entryPoint); Assert.ThrowsException(() => - entryPoint.SubmitAsync(new MockQuantumMachine(), new Dictionary() { { "count", "NaN" }, { "name", "test" } })); + entryPoint.SubmitAsync( + new MockQuantumMachine(), + new AzureSubmissionContext() { InputParameters = new Dictionary() { ["count"] = "NaN", ["name"] = "test" } })); } [TestMethod] @@ -102,7 +110,9 @@ public async Task FromSnippetDependsOnWorkspace() var entryPoint = entryPointGenerator.Generate("DependsOnWorkspace", null); Assert.IsNotNull(entryPoint); - var job = await entryPoint.SubmitAsync(new MockQuantumMachine(), new Dictionary()); + var job = await entryPoint.SubmitAsync( + new MockQuantumMachine(), + new AzureSubmissionContext()); Assert.IsNotNull(job); } @@ -139,10 +149,10 @@ public Task> ExecuteAsync(EntryP => ExecuteAsync(info, input, submissionContext, null, configureJobCallback); public Task> ExecuteAsync(EntryPointInfo info, TInput input, IQuantumMachineExecutionContext executionContext) - => ExecuteAsync(info, input, null as IQuantumMachineExecutionContext); + => ExecuteAsync(info, input, executionContext, null); public Task> ExecuteAsync(EntryPointInfo info, TInput input, IQuantumMachineExecutionContext executionContext, IQuantumMachine.ConfigureJob configureJobCallback) - => ExecuteAsync(info, input, executionContext, null as IQuantumMachine.ConfigureJob); + => ExecuteAsync(info, input, null, executionContext); public Task> ExecuteAsync(EntryPointInfo info, TInput input, IQuantumMachineSubmissionContext submissionContext, IQuantumMachineExecutionContext executionContext) => ExecuteAsync(info, input, submissionContext, executionContext, null); @@ -154,7 +164,7 @@ public Task SubmitAsync(EntryPointInfo SubmitAsync(info, input, null); public Task SubmitAsync(EntryPointInfo info, TInput input, IQuantumMachineSubmissionContext submissionContext) - => SubmitAsync(info, input, null, null); + => SubmitAsync(info, input, submissionContext, null); public Task SubmitAsync(EntryPointInfo info, TInput input, IQuantumMachineSubmissionContext submissionContext, IQuantumMachine.ConfigureJob configureJobCallback) => Task.FromResult(new MockQuantumMachineJob() as IQuantumMachineJob); diff --git a/src/Tests/AzureClientMagicTests.cs b/src/Tests/AzureClientMagicTests.cs index 6e91ad9491..b06833d336 100644 --- a/src/Tests/AzureClientMagicTests.cs +++ b/src/Tests/AzureClientMagicTests.cs @@ -188,17 +188,17 @@ public async Task GetActiveTargetAsync(IChannel channel) return ActiveTargetId.ToExecutionResult(); } - public async Task SubmitJobAsync(IChannel channel, string operationName, Dictionary inputParameters) + public async Task SubmitJobAsync(IChannel channel, AzureSubmissionContext submissionContext) { LastAction = AzureClientAction.SubmitJob; - SubmittedJobs.Add(operationName); + SubmittedJobs.Add(submissionContext.OperationName); return ExecuteStatus.Ok.ToExecutionResult(); } - public async Task ExecuteJobAsync(IChannel channel, string operationName, Dictionary inputParameters) + public async Task ExecuteJobAsync(IChannel channel, AzureSubmissionContext submissionContext) { LastAction = AzureClientAction.ExecuteJob; - ExecutedJobs.Add(operationName); + ExecutedJobs.Add(submissionContext.OperationName); return ExecuteStatus.Ok.ToExecutionResult(); }