/// <summary> /// Create the template output /// </summary> public virtual string TransformText() { this.Write(@"//---------------------------------------------------------------------------------------------------------------------- // <auto-generated /> // This code was generated by the Microsoft.Quantum.Qir.Runtime.Tools package. // The purpose of this source code file is to provide an entry-point for executing a QIR program. // It handles parsing of command line arguments, and it invokes an entry-point function exposed by the QIR program. //---------------------------------------------------------------------------------------------------------------------- #include <fstream> #include <iostream> #include <map> #include <memory> #include <vector> #include ""CLI11.hpp"" #include ""QirRuntime.hpp"" #include ""QirContext.hpp"" "); foreach (var header in RuntimeInitializer.Headers) { this.Write("#include \""); this.Write(this.ToStringHelper.ToStringWithCulture(header)); this.Write("\"\r\n"); } this.Write("\r\nusing namespace Microsoft::Quantum;\r\nusing namespace std;\r\n"); if (EntryPoint.ContainsArgumentType(DataType.ArrayType)) { this.Write(@" // 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); } "); } if (EntryPoint.ContainsArgumentType(DataType.RangeType) || EntryPoint.ContainsArrayType(DataType.RangeType)) { this.Write(@" // Auxiliary functions for interop with Q# Range type. using RangeTuple = tuple<int64_t, int64_t, int64_t>; struct InteropRange { int64_t Start; int64_t Step; int64_t End; InteropRange() : Start(0), Step(0), End(0){} InteropRange(RangeTuple rangeTuple) : Start(get<0>(rangeTuple)), Step(get<1>(rangeTuple)), End(get<2>(rangeTuple)){} }; unique_ptr<InteropRange> CreateInteropRange(RangeTuple rangeTuple) { unique_ptr<InteropRange> range(new InteropRange(rangeTuple)); return range; } InteropRange* TranslateRangeTupleToInteropRangePointer(RangeTuple& rangeTuple) { InteropRange* range = new InteropRange(rangeTuple); return range; } "); } if (EntryPoint.ContainsArrayType(DataType.RangeType)) { this.Write("\r\n// Auxiliary functions for interop with Q# Range[] type\r\ntemplate<typename T>\r\n" + "void FreePointerVector(vector<T*>& v)\r\n{\r\n for (auto p : v)\r\n {\r\n d" + "elete p;\r\n }\r\n}\r\n"); } if (EntryPoint.ContainsArgumentType(DataType.BoolType) || EntryPoint.ContainsArrayType(DataType.BoolType)) { this.Write("\r\n// Auxiliary functions for interop with Q# Bool type.\r\nconst char InteropFalseA" + "sChar = 0x0;\r\nconst char InteropTrueAsChar = 0x1;\r\nmap<string, bool> "); this.Write(this.ToStringHelper.ToStringWithCulture(QirCppInterop.CliOptionTransformerMapName(DataType.BoolType))); this.Write("{\r\n {\"0\", InteropFalseAsChar},\r\n {\"false\", InteropFalseAsChar},\r\n {\"1\", " + "InteropTrueAsChar},\r\n {\"true\", InteropTrueAsChar}\r\n};\r\n"); } if (EntryPoint.ContainsArgumentType(DataType.PauliType) || EntryPoint.ContainsArrayType(DataType.PauliType)) { this.Write("\r\n// Auxiliary functions for interop with Q# Pauli type.\r\nmap<string, PauliId> "); this.Write(this.ToStringHelper.ToStringWithCulture(QirCppInterop.CliOptionTransformerMapName(DataType.PauliType))); this.Write("{\r\n {\"PauliI\", PauliId::PauliId_I},\r\n {\"PauliX\", PauliId::PauliId_X},\r\n " + "{\"PauliY\", PauliId::PauliId_Y},\r\n {\"PauliZ\", PauliId::PauliId_Z}\r\n};\r\n\r\nchar " + "TranslatePauliToChar(PauliId& pauli)\r\n{\r\n return static_cast<char>(pauli);\r\n}" + "\r\n"); } if (EntryPoint.ContainsArgumentType(DataType.ResultType) || EntryPoint.ContainsArrayType(DataType.ResultType)) { this.Write("\r\n// Auxiliary functions for interop with Q# Result type.\r\nconst char InteropResu" + "ltZeroAsChar = 0x0;\r\nconst char InteropResultOneAsChar = 0x1;\r\nmap<string, char>" + " "); this.Write(this.ToStringHelper.ToStringWithCulture(QirCppInterop.CliOptionTransformerMapName(DataType.ResultType))); this.Write("{\r\n {\"0\", InteropResultZeroAsChar},\r\n {\"Zero\", InteropResultZeroAsChar},\r\n " + " {\"1\", InteropResultOneAsChar},\r\n {\"One\", InteropResultOneAsChar}\r\n};\r\n"); } if (EntryPoint.ContainsArgumentType(DataType.StringType) || EntryPoint.ContainsArrayType(DataType.StringType)) { this.Write("\r\n// Auxiliary functions for interop with Q# String type.\r\nconst char* TranslateS" + "tringToCharBuffer(string& s)\r\n{\r\n return s.c_str();\r\n}\r\n"); } this.Write("\r\nextern \"C\" void "); this.Write(this.ToStringHelper.ToStringWithCulture(EntryPoint.Name)); this.Write("(\r\n"); for (int i = 0; i < EntryPoint.Parameters.Count; i++) { var arg = EntryPoint.Parameters[i]; var isLastArg = i == (EntryPoint.Parameters.Count - 1); this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.InteropType())); this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.Name)); this.Write(this.ToStringHelper.ToStringWithCulture((isLastArg) ? "" : ",")); this.Write("\r\n"); } this.Write("); // QIR interop function.\r\n\r\nint main(int argc, char* argv[])\r\n{\r\n CLI::App " + "app(\"QIR Standalone Entry Point\");\r\n\r\n // Initialize runtime.\r\n"); var initializerReader = new StringReader(RuntimeInitializer.Generate()); string line; while ((line = initializerReader.ReadLine()) != null) { this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(line)); this.Write("\r\n"); } this.Write(@" // 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""); "); if (EntryPoint.Parameters.Count > 0) { this.Write(" // Add a command line option for each entry-point parameter.\r\n"); } foreach (var arg in EntryPoint.Parameters) { this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionType())); this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionVariableName())); this.Write(";\r\n"); if (arg.CliOptionVariableDefaultValue() != null) { this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionVariableName())); this.Write(" = "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionVariableDefaultValue())); this.Write(";\r\n"); } this.Write(" app.add_option(\""); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionName())); this.Write("\", "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionVariableName())); this.Write(", \""); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionDescription())); this.Write("\")\r\n ->required()"); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionTransformerMapName() != null ? "" : ";")); this.Write("\r\n"); if (arg.CliOptionTransformerMapName() != null) { this.Write(" ->transform(CLI::CheckedTransformer("); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionTransformerMapName())); this.Write(", CLI::ignore_case));\r\n"); } this.Write("\r\n"); } this.Write(" // After all the options have been added, parse arguments from the command li" + "ne.\r\n CLI11_PARSE(app, argc, argv);\r\n\r\n"); if (EntryPoint.Parameters.Count > 0) { this.Write(" // Cast parsed arguments to its interop types.\r\n"); } foreach (var arg in EntryPoint.Parameters) { if (arg.Type == DataType.ArrayType) { var arrayInteropTranslator = QirCppInterop.CliOptionTypeToInteropTypeTranslator(arg.ArrayType); if (arrayInteropTranslator == null) { this.Write(" unique_ptr<InteropArray> "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.UniquePtrVariableName())); this.Write(" = CreateInteropArray("); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionVariableName())); this.Write(");\r\n"); } else { var arrayCliOptionType = QirCppInterop.CliOptionType(arg.ArrayType); var arrayInteropType = QirCppInterop.InteropType(arg.ArrayType); this.Write(" vector<"); this.Write(this.ToStringHelper.ToStringWithCulture(arrayInteropType)); this.Write("> "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.IntermediateVariableName())); this.Write(";\r\n TranslateVector<"); this.Write(this.ToStringHelper.ToStringWithCulture(arrayCliOptionType)); this.Write(", "); this.Write(this.ToStringHelper.ToStringWithCulture(arrayInteropType)); this.Write(">("); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionVariableName())); this.Write(", "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.IntermediateVariableName())); this.Write(", "); this.Write(this.ToStringHelper.ToStringWithCulture(arrayInteropTranslator)); this.Write(");\r\n unique_ptr<InteropArray> "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.UniquePtrVariableName())); this.Write(" = CreateInteropArray("); this.Write(this.ToStringHelper.ToStringWithCulture(arg.IntermediateVariableName())); this.Write(");\r\n"); } this.Write(" InteropArray* "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.InteropVariableName())); this.Write(" = "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.UniquePtrVariableName())); this.Write(".get();\r\n"); } else { var interopTranslator = QirCppInterop.CliOptionTypeToInteropTypeTranslator(arg.Type); if (interopTranslator == null) { this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.InteropType())); this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.InteropVariableName())); this.Write(" = "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionVariableName())); this.Write(";\r\n"); } else { this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.InteropType())); this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.InteropVariableName())); this.Write(" = "); this.Write(this.ToStringHelper.ToStringWithCulture(interopTranslator)); this.Write("("); this.Write(this.ToStringHelper.ToStringWithCulture(arg.CliOptionVariableName())); this.Write(");\r\n"); } } this.Write("\r\n"); } this.Write(@" // 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. "); this.Write(this.ToStringHelper.ToStringWithCulture(EntryPoint.Name)); this.Write("(\r\n"); for (int i = 0; i < EntryPoint.Parameters.Count; i++) { var arg = EntryPoint.Parameters[i]; var isLastArg = i == (EntryPoint.Parameters.Count - 1); this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(arg.InteropVariableName())); this.Write(this.ToStringHelper.ToStringWithCulture((isLastArg) ? "" : ",")); this.Write("\r\n"); } this.Write(" );\r\n\r\n // Flush the output of the simulation.\r\n simulatorOutputStream->" + "flush();\r\n if (simulationOutputFileStream.is_open())\r\n {\r\n simulati" + "onOutputFileStream.close();\r\n }\r\n\r\n return 0;\r\n}\r\n"); return(this.GenerationEnvironment.ToString()); }