Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Expose output format #726

Merged
merged 1 commit into from
Sep 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions src/AzureClient/AzureClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@

namespace Microsoft.Quantum.IQSharp.AzureClient
{
/// <summary>
/// Supported output data formats for QIR.
/// </summary>
internal static class OutputFormat
{
public const string QirResultsV1 = "microsoft.qir-results.v1";

public const string QuantumResultsV1 = "microsoft.quantum-results.v1";

public const string ResourceEstimatesV1 = "microsoft.resource-estimates.v1";
}

/// <inheritdoc/>
public class AzureClient : IAzureClient
{
Expand Down Expand Up @@ -637,7 +649,7 @@ public async Task<ExecutionResult> GetJobResultAsync(IChannel? channel, string?
}
}

private async Task<ExecutionResult> CreateOutput(CloudJob job, IChannel? channel, CancellationToken cancellationToken)
internal async Task<ExecutionResult> CreateOutput(CloudJob job, IChannel? channel, CancellationToken cancellationToken)
{
async Task<Stream> ReadHttp()
{
Expand All @@ -651,16 +663,22 @@ async Task<Stream> ReadHttp()
using var stream = job.OutputDataUri.IsFile
? File.OpenRead(job.OutputDataUri.LocalPath)
: await ReadHttp();
if (this.ActiveTarget?.TargetId?.StartsWith(MicrosoftSimulator) ?? false)

if (job.OutputDataFormat == OutputFormat.QirResultsV1)
{
var (messages, result) = ParseSimulatorOutput(stream);
channel?.Stdout(messages);
return result.ToExecutionResult();
}
else
else if (job.OutputDataFormat == OutputFormat.QuantumResultsV1)
{
return stream.ToHistogram(channel, Logger).ToExecutionResult();
}
else
{
channel?.Stderr($"Job ID {job.Id} has unsupported output format: {job.OutputDataFormat}");
return AzureClientError.JobOutputDownloadFailed.ToExecutionResult();
}
}

private static (string Messages, string Result) ParseSimulatorOutput(Stream stream)
Expand All @@ -671,7 +689,7 @@ private static (string Messages, string Result) ParseSimulatorOutput(Stream stre
var line = String.Empty;
while ((line = reader.ReadLine()) != null)
{
outputLines.Add(line.Trim());
outputLines.Add(line.Trim());
}
}

Expand Down
19 changes: 15 additions & 4 deletions src/AzureClient/Mocks/MockCloudJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ public float? EstimatedTotal
/// </summary>
internal class MockJobDetails : JobDetails
{
public MockJobDetails(string containerUri, string inputDataFormat, string providerId, string target)
public MockJobDetails(string containerUri, string inputDataFormat, string providerId, string target, string outputDataFormat)
: base(containerUri: containerUri,
inputDataFormat: inputDataFormat,
providerId: providerId,
target: target)
{
OutputDataFormat = outputDataFormat;
}

private MockCostEstimate? costEstimate;
Expand Down Expand Up @@ -110,14 +111,15 @@ internal class MockCloudJob : CloudJob
private string _id;
private string? _outputFile;

public MockCloudJob(string? id = null)
public MockCloudJob(string? id = null, string outputFormat = OutputFormat.QuantumResultsV1)
: base(
new MockAzureWorkspace("mockSubscriptionId", "mockResourceGroupName", "mockWorkspaceName", "mockLocation"),
new MockJobDetails(
containerUri: string.Empty,
inputDataFormat: string.Empty,
providerId: string.Empty,
target: string.Empty
target: string.Empty,
outputDataFormat: outputFormat
))
{
_id = id ?? Guid.NewGuid().ToString();
Expand All @@ -135,7 +137,16 @@ public override Uri OutputDataUri
{
var path = Path.GetTempFileName();
using var outputFile = new StreamWriter(path);
outputFile.WriteLine(@"{'Histogram':['0',0.5,'1',0.5]}");
if (OutputDataFormat == OutputFormat.QirResultsV1)
{
outputFile.WriteLine("\"This is a message.\"");
outputFile.WriteLine("\"The is a two-line");
outputFile.WriteLine("string result.\"");
}
else
{
outputFile.WriteLine(@"{'Histogram':['0',0.5,'1',0.5]}");
}

_outputFile = path;
}
Expand Down
29 changes: 29 additions & 0 deletions src/Tests/AzureClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,35 @@ public void TestJobExecution()
Assert.IsNotNull(histogram);
}

[TestMethod]
public void TestJobOutputFormats()
{
var services = Startup.CreateServiceProvider("Workspace");
var azureClient = (AzureClient)services.GetRequiredService<IAzureClient>();

// connect
var targets = ExpectSuccess<IEnumerable<TargetStatusInfo>>(ConnectToWorkspaceAsync(azureClient));
Assert.IsFalse(targets.Any());

// add a target
var azureWorkspace = azureClient.ActiveWorkspace as MockAzureWorkspace;
Assert.IsNotNull(azureWorkspace);
azureWorkspace?.AddProviders("microsoft");

// set the active target
var target = ExpectSuccess<TargetStatusInfo>(azureClient.SetActiveTargetAsync(new MockChannel(), "microsoft.simulator"));
Assert.AreEqual("microsoft.simulator", target.TargetId);

var qirResultsJob = new MockCloudJob(null, OutputFormat.QirResultsV1);
var quantumResultsJob = new MockCloudJob(null, OutputFormat.QuantumResultsV1);

var histogram = ExpectSuccess<Histogram>(azureClient.CreateOutput(quantumResultsJob, new MockChannel(), CancellationToken.None));
Assert.IsNotNull(histogram);

var stringOutput = ExpectSuccess<string>(azureClient.CreateOutput(qirResultsJob, new MockChannel(), CancellationToken.None));
Assert.IsNotNull(stringOutput);
}

[TestMethod]
public void TestJobExecutionWithArrayInput()
{
Expand Down