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
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Collections.Generic;
using System.IO;
using System.Text;

using Xunit;

using Microsoft.Quantum.Qir.Tools.Driver;
using Microsoft.Quantum.QsCompiler.BondSchemas.Execution;

namespace Tests.Microsoft.Quantum.Qir.Tools
{
public class QirDriverGeneratorTests
{
private static string TestArtifactsDirectory = Path.Combine("TestArtifacts", "FullStateDriverGenerator");
private static string TestCasesDirectory = Path.Combine("TestCases", "FullStateDriverGenerator");
private static IDictionary<string, EntryPointOperation> TestCases =
new Dictionary<string, EntryPointOperation>
{
{
"UseNoArgs",
new EntryPointOperation{Name = "UseNoArgs"}
},
{
"UseBoolArg",
new EntryPointOperation
{
Name = "UseBoolArg",
Parameters = new List<Parameter>{new Parameter{ Name = "BoolArg", Type = DataType.BoolType}}
}
},
{
"UseBoolArrayArg",
new EntryPointOperation
{
Name = "UseBoolArrayArg",
Parameters = new List<Parameter>{new Parameter{ Name = "BoolArrayArg", Type = DataType.ArrayType, ArrayType = DataType.BoolType}}
}
},
{
"UseDoubleArg",
new EntryPointOperation
{
Name = "UseDoublArg",
Parameters = new List<Parameter>{new Parameter{ Name = "DoubleArg", Type = DataType.DoubleType}}
}
},
{
"UseDoubleArrayArg",
new EntryPointOperation
{
Name = "UseDoubleArrayArg",
Parameters = new List<Parameter>{new Parameter{ Name = "DoubleArrayArg", Type = DataType.ArrayType, ArrayType = DataType.DoubleType}}
}
},
{
"UseIntegerArg",
new EntryPointOperation
{
Name = "UseIntegerArg",
Parameters = new List<Parameter>{new Parameter{ Name = "IntegerArg", Type = DataType.IntegerType}}
}
},
{
"UseIntegerArrayArg",
new EntryPointOperation
{
Name = "UseIntegerArrayArg",
Parameters = new List<Parameter>{new Parameter{ Name = "IntegerArrayArg", Type = DataType.ArrayType, ArrayType = DataType.IntegerType}}
}
},
{
"UsePauliArg",
new EntryPointOperation
{
Name = "UsePauliArg",
Parameters = new List<Parameter>{new Parameter{ Name = "PauliArg", Type = DataType.PauliType}}
}
},
{
"UsePauliArrayArg",
new EntryPointOperation
{
Name = "UsePauliArrayArg",
Parameters = new List<Parameter>{new Parameter{ Name = "PauliArrayArg", Type = DataType.ArrayType, ArrayType = DataType.PauliType}}
}
},
{
"UseRangeArg",
new EntryPointOperation
{
Name = "UseRangeArg",
Parameters = new List<Parameter>{new Parameter{ Name = "RangeArg", Type = DataType.RangeType}}
}
},
{
"UseRangeArrayArg",
new EntryPointOperation
{
Name = "UseRangeArrayArg",
Parameters = new List<Parameter>{new Parameter{ Name = "RangeArrayArg", Type = DataType.ArrayType, ArrayType = DataType.RangeType}}
}
},
{
"UseResultArg",
new EntryPointOperation
{
Name = "UseResultArg",
Parameters = new List<Parameter>{new Parameter{ Name = "ResultArg", Type = DataType.ResultType}}
}
},
{
"UseResultArrayArg",
new EntryPointOperation
{
Name = "UseResultArrayArg",
Parameters = new List<Parameter>{new Parameter{ Name = "ResultArrayArg", Type = DataType.ArrayType, ArrayType = DataType.ResultType}}
}
},
{
"UseStringArg",
new EntryPointOperation
{
Name = "UseStringArg",
Parameters = new List<Parameter>{new Parameter{ Name = "StringArg", Type = DataType.StringType}}
}
},
{
"UseMiscArgs",
new EntryPointOperation
{
Name = "UseMiscArgs",
Parameters = new List<Parameter>{
new Parameter{ Name = "BoolArg", Type = DataType.BoolType},
new Parameter{ Name = "IntegerArrayArg", Position = 1, Type = DataType.ArrayType, ArrayType = DataType.IntegerType},
new Parameter{ Name = "RangeArg", Position = 2, Type = DataType.RangeType},
new Parameter{ Name = "StringArg", Position = 3, Type = DataType.StringType}
}
}
}
};

[Theory]
[InlineData("UseNoArgs")]
[InlineData("UseBoolArg")]
[InlineData("UseBoolArrayArg")]
[InlineData("UseDoubleArg")]
[InlineData("UseDoubleArrayArg")]
[InlineData("UseIntegerArg")]
[InlineData("UseIntegerArrayArg")]
[InlineData("UsePauliArg")]
[InlineData("UsePauliArrayArg")]
[InlineData("UseRangeArg")]
[InlineData("UseRangeArrayArg")]
[InlineData("UseResultArg")]
[InlineData("UseResultArrayArg")]
[InlineData("UseStringArg")]
[InlineData("UseMiscArgs")]
public void GenerateFullStateSimulatorDriver(string testCase)
{
var entryPointOperation = TestCases[testCase];
var driverGenerator = new QirFullStateDriverGenerator();
var driverFileName = $"{testCase}.cpp";
var verificationCppSourceCode = File.ReadAllText(Path.Combine(TestCasesDirectory, driverFileName));
if (!Directory.Exists(TestArtifactsDirectory))
{
Directory.CreateDirectory(TestArtifactsDirectory);
}

var generatedStream = File.Create(Path.Combine(TestArtifactsDirectory, driverFileName));
driverGenerator.GenerateAsync(entryPointOperation, generatedStream).Wait();
var generatedStreamReader = new StreamReader(generatedStream, Encoding.UTF8);
var generatedCppSourceCode = generatedStreamReader.ReadToEnd();
Assert.Equal(verificationCppSourceCode, generatedCppSourceCode);
generatedStream.Close();

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
// <auto-generated />
//------------------------------------------------------------------------------

#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <vector>

#include "CLI11.hpp"

#include "QirRuntime.hpp"
#include "QirContext.hpp"

#include "SimFactory.hpp"

using namespace Microsoft::Quantum;
using namespace std;

// Auxiliary functions for interop with Q# Bool type.
const char InteropFalseAsChar = 0x0;
const char InteropTrueAsChar = 0x1;
map<string, bool> BoolAsCharMap{
{"0", InteropFalseAsChar},
{"false", InteropFalseAsChar},
{"1", InteropTrueAsChar},
{"true", InteropTrueAsChar}
};

extern "C" void UseBoolArg(
char BoolArg
); // QIR interop function.

int main(int argc, char* argv[])
{
CLI::App app("QIR Standalone Entry Point");

// Initialize simulator.
unique_ptr<IRuntimeDriver> sim = CreateFullstateSimulator();
QirContextScope qirctx(sim.get(), false /*trackAllocatedObjects*/);

// Add the --simulation-output option.
string simulationOutputFile;
CLI::Option* simulationOutputFileOpt = app.add_option(
"--simulation-output",
simulationOutputFile,
"File where the output produced during the simulation is written");

// Add a command line option for each entry-point parameter.
char BoolArgCli;
BoolArgCli = InteropFalseAsChar;
app.add_option("--BoolArg", BoolArgCli, "Option to provide a value for the BoolArg parameter")
->required()
->transform(CLI::CheckedTransformer(BoolAsCharMap, CLI::ignore_case));

// After all the options have been added, parse arguments from the command line.
CLI11_PARSE(app, argc, argv);

// Cast parsed arguments to its interop types.
char BoolArgInterop = BoolArgCli;

// Redirect the simulator output from std::cout if the --simulation-output option is present.
ostream* simulatorOutputStream = &cout;
ofstream simulationOutputFileStream;
if (!simulationOutputFileOpt->empty())
{
simulationOutputFileStream.open(simulationOutputFile);
SetOutputStream(simulationOutputFileStream);
simulatorOutputStream = &simulationOutputFileStream;
}

// Execute the entry point operation.
UseBoolArg(
BoolArgInterop
);

// Flush the output of the simulation.
simulatorOutputStream->flush();
if (simulationOutputFileStream.is_open())
{
simulationOutputFileStream.close();
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//------------------------------------------------------------------------------
// This code was generated by a tool.
// <auto-generated />
//------------------------------------------------------------------------------

#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <vector>

#include "CLI11.hpp"

#include "QirRuntime.hpp"
#include "QirContext.hpp"

#include "SimFactory.hpp"

using namespace Microsoft::Quantum;
using namespace std;

// Auxiliary functions for interop with Q# Array type.
struct InteropArray
{
int64_t Size;
void* Data;

InteropArray(int64_t size, void* data) :
Size(size),
Data(data){}
};

template<typename T>
unique_ptr<InteropArray> CreateInteropArray(vector<T>& v)
{
unique_ptr<InteropArray> array(new InteropArray(v.size(), v.data()));
return array;
}

template<typename S, typename D>
void TranslateVector(vector<S>& sourceVector, vector<D>& destinationVector, function<D(S&)> translationFunction)
{
destinationVector.resize(sourceVector.size());
transform(sourceVector.begin(), sourceVector.end(), destinationVector.begin(), translationFunction);
}

// Auxiliary functions for interop with Q# Bool type.
const char InteropFalseAsChar = 0x0;
const char InteropTrueAsChar = 0x1;
map<string, bool> BoolAsCharMap{
{"0", InteropFalseAsChar},
{"false", InteropFalseAsChar},
{"1", InteropTrueAsChar},
{"true", InteropTrueAsChar}
};

extern "C" void UseBoolArrayArg(
InteropArray* BoolArrayArg
); // QIR interop function.

int main(int argc, char* argv[])
{
CLI::App app("QIR Standalone Entry Point");

// Initialize simulator.
unique_ptr<IRuntimeDriver> sim = CreateFullstateSimulator();
QirContextScope qirctx(sim.get(), false /*trackAllocatedObjects*/);

// Add the --simulation-output option.
string simulationOutputFile;
CLI::Option* simulationOutputFileOpt = app.add_option(
"--simulation-output",
simulationOutputFile,
"File where the output produced during the simulation is written");

// Add a command line option for each entry-point parameter.
vector<char> BoolArrayArgCli;
app.add_option("--BoolArrayArg", BoolArrayArgCli, "Option to provide a value for the BoolArrayArg parameter")
->required()
->transform(CLI::CheckedTransformer(BoolAsCharMap, CLI::ignore_case));

// After all the options have been added, parse arguments from the command line.
CLI11_PARSE(app, argc, argv);

// Cast parsed arguments to its interop types.
unique_ptr<InteropArray> BoolArrayArgUniquePtr = CreateInteropArray(BoolArrayArgCli);
InteropArray* BoolArrayArgInterop = BoolArrayArgUniquePtr.get();

// Redirect the simulator output from std::cout if the --simulation-output option is present.
ostream* simulatorOutputStream = &cout;
ofstream simulationOutputFileStream;
if (!simulationOutputFileOpt->empty())
{
simulationOutputFileStream.open(simulationOutputFile);
SetOutputStream(simulationOutputFileStream);
simulatorOutputStream = &simulationOutputFileStream;
}

// Execute the entry point operation.
UseBoolArrayArg(
BoolArrayArgInterop
);

// Flush the output of the simulation.
simulatorOutputStream->flush();
if (simulationOutputFileStream.is_open())
{
simulationOutputFileStream.close();
}

return 0;
}
Loading