Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,6 @@ ASALocalRun/
/src/Simulation/Simulators.Tests/TestProjects/QSharpExe/built
/src/Simulation/Simulators.Tests/TestProjects/TargetedExe/built
dbw_test

# Controller test artifacts
/src/Qir/Controller/test-artifacts/
19 changes: 19 additions & 0 deletions Simulation.sln
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Controller", "Controller",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QirController", "src\Qir\Controller\QirController.csproj", "{A77E6661-D143-4E3E-BCD1-8E321A966829}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests.QirController", "src\Qir\Controller\Tests.QirController\Tests.QirController.csproj", "{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -769,6 +771,22 @@ Global
{A77E6661-D143-4E3E-BCD1-8E321A966829}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{A77E6661-D143-4E3E-BCD1-8E321A966829}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{A77E6661-D143-4E3E-BCD1-8E321A966829}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.Debug|x64.ActiveCfg = Debug|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.Debug|x64.Build.0 = Debug|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.Release|Any CPU.Build.0 = Release|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.Release|x64.ActiveCfg = Release|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.Release|x64.Build.0 = Release|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -824,6 +842,7 @@ Global
{D7D34736-A719-4B45-A33F-2723F59EC29D} = {A7DB7367-9FD6-4164-8263-A05077BE54AB}
{4E07F247-ED93-4497-8B58-022314308E67} = {F6C2D4C0-12DC-40E3-9C86-FA5308D9B567}
{A77E6661-D143-4E3E-BCD1-8E321A966829} = {4E07F247-ED93-4497-8B58-022314308E67}
{2E4B9604-A5CD-4B49-B1D4-A7AC8ABAEF68} = {4E07F247-ED93-4497-8B58-022314308E67}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {929C0464-86D8-4F70-8835-0A5EAF930821}
Expand Down
14 changes: 14 additions & 0 deletions src/Qir/Controller/Constant.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace Microsoft.Quantum.Qir
{
public static class Constant
{
// TODO: errors will be added as dependencies are implemented.
public static class ErrorCode
{
public const string InternalError = "InternalError";
}
}
}
99 changes: 85 additions & 14 deletions src/Qir/Controller/Controller.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,97 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Quantum.Qir.Driver;
using Microsoft.Quantum.Qir.Executable;
using Microsoft.Quantum.Qir.Model;
using Microsoft.Quantum.Qir.Utility;
using QirExecutionWrapperSerialization = Microsoft.Quantum.QsCompiler.BondSchemas.QirExecutionWrapper.Protocols;

namespace Microsoft.Quantum.Qir
{
internal static class Controller
public static class Controller
{
internal static void Execute(
FileInfo input,
FileInfo output,
FileInfo error)
private const string SourceDirectoryPath = "src";
private const string BinaryDirectoryPath = "bin";
private const string ExecutableName = "simulation.exe";

public static async Task ExecuteAsync(
FileInfo inputFile,
FileInfo outputFile,
DirectoryInfo libraryDirectory,
DirectoryInfo includeDirectory,
FileInfo errorFile,
IQirDriverGenerator driverGenerator,
IQirExecutableGenerator executableGenerator,
IQuantumExecutableRunner executableRunner,
ILogger logger)
{
var outputFileStream = output.Exists ? output.OpenWrite() : output.Create();
outputFileStream.Write(new UTF8Encoding().GetBytes("output"));
outputFileStream.Flush();
outputFileStream.Close();
var errorFileStream = error.Exists ? error.OpenWrite() : error.Create();
errorFileStream.Write(new UTF8Encoding().GetBytes("error"));
errorFileStream.Flush();
errorFileStream.Close();
try
{
// Step 1: Parse input.
logger.LogInfo("Parsing input.");
using var inputFileStream = inputFile.OpenRead();
var input = QirExecutionWrapperSerialization.DeserializeFromFastBinary(inputFileStream);

// Step 32: Create driver.
logger.LogInfo("Creating driver file.");
var sourceDirectory = new DirectoryInfo(SourceDirectoryPath);
await driverGenerator.GenerateQirDriverCppAsync(sourceDirectory, input.EntryPoint, input.QirBytecode);

// Step 3: Create executable.
logger.LogInfo("Compiling and linking executable.");
var binaryDirectory = new DirectoryInfo(BinaryDirectoryPath);
var executableFile = new FileInfo(Path.Combine(BinaryDirectoryPath, ExecutableName));
await executableGenerator.GenerateExecutableAsync(executableFile, sourceDirectory, libraryDirectory, includeDirectory);

// Step 4: Run executable.
logger.LogInfo("Running executable.");
using var outputFileStream = outputFile.OpenWrite();
await executableRunner.RunExecutableAsync(executableFile, input.EntryPoint, outputFile);
}
catch (Exception e)
{
logger.LogError("An error has been encountered. Will write an error to the error file and delete any output that has been generated.");
logger.LogException(e);
await WriteExceptionToFileAsync(e, errorFile);
}
}

private static async Task WriteExceptionToFileAsync(Exception e, FileInfo errorFile)
{
// Create the error object.
Error error;
if (e is ControllerException controllerException)
{
error = new Error
{
Code = controllerException.Code,
Message = controllerException.Message,
};
}
else
{
error = new Error
{
Code = Constant.ErrorCode.InternalError,
Message = ErrorMessages.InternalError,
};
}

// Serialize the error to JSON.
var errorJson = JsonSerializer.Serialize(error, new JsonSerializerOptions
{
WriteIndented = true,
});

// Write the error to the error file.
using var errorFileStream = errorFile.OpenWrite();
using var streamWriter = new StreamWriter(errorFileStream);
await streamWriter.WriteAsync(errorJson);
}
}
}
21 changes: 21 additions & 0 deletions src/Qir/Controller/ControllerException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;

namespace Microsoft.Quantum.Qir
{
/// <summary>
/// Exception that represents an error that can be written to an error file.
/// </summary>
public class ControllerException : Exception
{
public ControllerException(string message, string code)
: base(message)
{
Code = code;
}

public string Code { get; }
}
}
22 changes: 22 additions & 0 deletions src/Qir/Controller/Driver/IQirDriverGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Quantum.QsCompiler.BondSchemas.EntryPoint;

namespace Microsoft.Quantum.Qir.Driver
{
public interface IQirDriverGenerator
{
/// <summary>
/// Generates the C++ driver source file and writes the bytecode to a file.
/// </summary>
/// <param name="sourceDirectory">Directory to which driver and bytecode will be written.</param>
/// <param name="entryPointOperation">Entry point information.</param>
/// <param name="bytecode">The QIR bytecode.</param>
/// <returns></returns>
Task GenerateQirDriverCppAsync(DirectoryInfo sourceDirectory, EntryPointOperation entryPointOperation, ArraySegment<byte> bytecode);
}
}
26 changes: 26 additions & 0 deletions src/Qir/Controller/Driver/QirDriverGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Quantum.Qir.Utility;
using Microsoft.Quantum.QsCompiler.BondSchemas.EntryPoint;

namespace Microsoft.Quantum.Qir.Driver
{
public class QirDriverGenerator : IQirDriverGenerator
{
private readonly ILogger logger;

public QirDriverGenerator(ILogger logger)
{
this.logger = logger;
}

public Task GenerateQirDriverCppAsync(DirectoryInfo sourceDirectory, EntryPointOperation entryPointOperation, ArraySegment<byte> bytecode)
{
throw new NotImplementedException();
}
}
}
72 changes: 72 additions & 0 deletions src/Qir/Controller/ErrorMessages.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading