From 8701b80a407bf8243eaba94808c1057835db5199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Zaragoza=20Cort=C3=A9s?= Date: Mon, 22 Mar 2021 21:01:18 -0700 Subject: [PATCH 1/8] Update C++ entry-point reference driver to use latest QIR emission. --- .../StandaloneInputReference/CMakeLists.txt | 2 +- .../StandaloneInputReference/qir-driver.cpp | 215 +++++++++--------- .../qir-standalone-input-reference.csproj | 2 +- .../qsharp/qir-standalone-input-reference.qs | 19 +- 4 files changed, 123 insertions(+), 115 deletions(-) diff --git a/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt b/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt index fb694fa533b..56030445c9c 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt +++ b/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt @@ -32,7 +32,7 @@ install(TARGETS qir-input-reference-standalone RUNTIME DESTINATION "${CMAKE_BINA include(CTest) add_test( NAME qir-input-reference-standalone - COMMAND qir-input-reference-standalone --int-value 1 --integer-array 1 2 3 4 5 --double-value 0.5 --double-array 0.1 0.2 0.3 0.4 0.5 --bool-value true --bool-array true TRUE false fALSe 1 --pauli-value PauliX --pauli-array PauliI paulix PAULIY PAulIZ --range-value 1 2 10 --range-array 1 2 10 5 5 50 10 1 20 --string-value ASampleString --result-value one --result-array one ONE true TRUE 1 zero ZERO false FALSE 0 + COMMAND qir-input-reference-standalone --int-value 1 --integer-array 1 2 3 4 5 --double-value 0.5 --double-array 0.1 0.2 0.3 0.4 0.5 --bool-value true --bool-array true TRUE false fALSe 1 --pauli-value PauliI --pauli-array PauliI paulix PAULIY PAulIZ --range-value 1 2 10 --range-array 1 2 10 5 5 50 10 1 20 --string-value ASampleString --result-value one --result-array one ONE 1 0 zero ZERO ) # set the environment path for loading shared libs the tests are using diff --git a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp index ee1d07a7cde..f41aa92501b 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp +++ b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#include // for memcpy #include #include #include @@ -10,30 +9,47 @@ #include "CLI11.hpp" -#include "CoreTypes.hpp" #include "QirContext.hpp" -#include "QirTypes.hpp" -#include "QirRuntimeApi_I.hpp" #include "SimFactory.hpp" -#include "QirRuntime.hpp" using namespace Microsoft::Quantum; using namespace std; +struct InteropArray +{ + int64_t Size; + void* Data; +}; + +struct InteropRange +{ + int64_t Start; + int64_t Step; + int64_t End; +}; + // This is the function corresponding to the QIR entry-point. -extern "C" int64_t Quantum__StandaloneSupportedInputs__ExerciseInputs__body( // NOLINT +extern "C" void Quantum__StandaloneSupportedInputs__ExerciseInputs( // NOLINT int64_t intValue, + InteropArray* integerArray, double doubleValue, - Result resultValue, - QirString* stringValue); - -const char FalseAsChar = 0x0; -const char TrueAsChar = 0x1; + InteropArray* doubleArray, + char boolValue, + InteropArray* boolArray, + char pauliValue, + InteropArray* pauliArray, + InteropRange* rangeValue, + char resultValue, + InteropArray* resultArray, + const char* stringValue); + +const char InteropFalseAsChar = 0x0; +const char InteropTrueAsChar = 0x1; map BoolAsCharMap{ - {"0", FalseAsChar}, - {"false", FalseAsChar}, - {"1", TrueAsChar}, - {"true", TrueAsChar}}; + {"0", InteropFalseAsChar}, + {"false", InteropFalseAsChar}, + {"1", InteropTrueAsChar}, + {"true", InteropTrueAsChar}}; map PauliMap{ {"PauliI", PauliId::PauliId_I}, @@ -41,59 +57,55 @@ map PauliMap{ {"PauliY", PauliId::PauliId_Y}, {"PauliZ", PauliId::PauliId_Z}}; +const char InteropResultZeroAsChar = 0x0; +const char InteropResultOneAsChar = 0x1; map ResultAsCharMap{ - {"0", FalseAsChar}, - {"Zero", FalseAsChar}, - {"false", FalseAsChar}, - {"1", TrueAsChar}, - {"One", TrueAsChar}, - {"true", TrueAsChar}}; + {"0", InteropResultZeroAsChar}, + {"Zero", InteropResultZeroAsChar}, + {"1", InteropResultOneAsChar}, + {"One", InteropResultOneAsChar} +}; template -QirArray* CreateQirArray(T* dataBuffer, int64_t itemCount) +unique_ptr CreateInteropArray(vector v) { - int32_t typeSize = sizeof(T); // NOLINT - QirArray* qirArray = quantum__rt__array_create_1d(typeSize, itemCount); - memcpy(qirArray->buffer, dataBuffer, typeSize * itemCount); - return qirArray; + unique_ptr array(new InteropArray()); + array->Size = v.size(); + array->Data = v.data(); + return array; } -template -unique_ptr TranslateVectorToBuffer(vectorsourceVector, function translationFunction) +using RangeTuple = tuple; +unique_ptr CreateInteropRange(RangeTuple rangeTuple) { - unique_ptr buffer (new D[sourceVector.size()]); - for (int index = 0; index < sourceVector.size(); index++) - { - buffer[index] = translationFunction(sourceVector[index]); - } - - return buffer; + unique_ptr range(new InteropRange()); + range->Start = get<0>(rangeTuple); + range->Step = get<1>(rangeTuple); + range->End = get<2>(rangeTuple); + return range; } -using RangeTuple = tuple; -QirRange TranslateRangeTupleToQirRange(RangeTuple rangeTuple) +char TranslatePauliToChar(PauliId pauli) { - QirRange qirRange = { - get<0>(rangeTuple), // Start - get<1>(rangeTuple), // Step - get<2>(rangeTuple) // End - }; - - return qirRange; + return static_cast(pauli); } -bool TranslateCharToBool(char boolAsChar) +template +void TranslateVector(vectorsourceVector, vector& destinationVector, function translationFunction) { - return (boolAsChar != FalseAsChar); + destinationVector.resize(sourceVector.size()); + transform(sourceVector.begin(), sourceVector.end(), destinationVector.begin(), translationFunction); } -// Result Zero and One are opaque types defined by the runtime. They are declared here and initialized before executing -// the simulation. -Result RuntimeResultZero = nullptr; -Result RuntimeResultOne = nullptr; -Result TranslateCharToResult(char resultAsChar) +InteropRange TranslateRangeTupleToInteropRange(RangeTuple rangeTuple) { - return resultAsChar == FalseAsChar ? RuntimeResultZero : RuntimeResultOne; + InteropRange range = { + get<0>(rangeTuple), // Start + get<1>(rangeTuple), // Step + get<2>(rangeTuple) // End + }; + + return range; } int main(int argc, char* argv[]) @@ -103,20 +115,14 @@ int main(int argc, char* argv[]) // Initialize simulator. unique_ptr sim = CreateFullstateSimulator(); QirContextScope qirctx(sim.get(), false /*trackAllocatedObjects*/); - RuntimeResultZero = sim->UseZero(); - RuntimeResultOne = sim->UseOne(); - // Add the --simulation-output and --operation-output options. - // N.B. These options should be present in all standalone drivers. + // Add the --simulation-output options. + // N.B. This option should be present in all standalone drivers. string simulationOutputFile; CLI::Option* simulationOutputFileOpt = app.add_option( "-s,--simulation-output", simulationOutputFile, "File where the output produced during the simulation is written"); - string operationOutputFile; - CLI::Option* operationOutputFileOpt = app.add_option( - "-o,--operation-output", operationOutputFile, "File where the output of the Q# operation is written"); - // Add the options that correspond to the parameters that the QIR entry-point needs. // Option for a Q# Int type. int64_t intValue = 0; @@ -135,8 +141,10 @@ int main(int argc, char* argv[]) app.add_option("--double-array", doubleVector, "A double array")->required(); // Option for a Q# Bool type. - bool boolValue = false; - app.add_option("--bool-value", boolValue, "A bool value")->required(); + char boolAsCharValue = InteropFalseAsChar; + app.add_option("--bool-value", boolAsCharValue, "A bool value") + ->required() + ->transform(CLI::CheckedTransformer(BoolAsCharMap, CLI::ignore_case)); // Option for a Q# Array type. // N.B. For command line parsing, a char vector is used because vector is a specialized version of vector not @@ -161,8 +169,8 @@ int main(int argc, char* argv[]) // Option for Q# Range type. // N.B. RangeTuple type is used here instead of QirRange because CLI11 supports tuple parsing which is leveraged and // the tuple is later translated to QirRange. - RangeTuple rangeValue(0, 0, 0); - app.add_option("--range-value", rangeValue, "A Range value (start, step, end)")->required(); + RangeTuple rangeTuple(0, 0, 0); + app.add_option("--range-value", rangeTuple, "A Range value (start, step, end)")->required(); // Option for a Q# Array type. vector rangeTupleVector; @@ -171,7 +179,7 @@ int main(int argc, char* argv[]) // Option for Q# Result type. // N.B. This is implemented as a char rather than a boolean to be consistent with the way an array of results has to // be implemented. - char resultAsCharValue = FalseAsChar; + char resultAsCharValue = InteropResultZeroAsChar; app.add_option("--result-value", resultAsCharValue, "A Result value") ->required() ->transform(CLI::CheckedTransformer(ResultAsCharMap, CLI::ignore_case)); @@ -192,37 +200,31 @@ int main(int argc, char* argv[]) CLI11_PARSE(app, argc, argv); // Translate values to its final form after parsing. - // Create a QirArray of integer values. - QirArray* qirIntegerArray = CreateQirArray(integerVector.data(), integerVector.size()); - - // Create a QirArray of double values. - QirArray* qirDoubleArray = CreateQirArray(doubleVector.data(), doubleVector.size()); - - // Create a QirArray of bool values. - unique_ptr boolArray = TranslateVectorToBuffer(boolAsCharVector, TranslateCharToBool); - QirArray* qirboolArray = CreateQirArray(boolArray.get(), boolAsCharVector.size()); + // Create an interop array of integer values. + unique_ptr integerArray = CreateInteropArray(integerVector); - // Create a QirArray of Pauli values. - QirArray* qirPauliArray = CreateQirArray(pauliVector.data(), pauliVector.size()); + // Create an interop array of double values. + unique_ptr doubleArray = CreateInteropArray(doubleVector); - // Create a QirRange. - QirRange qirRange = TranslateRangeTupleToQirRange(rangeValue); + // Create an interop array of bool values. + unique_ptr boolArray = CreateInteropArray(boolAsCharVector); - // Create a QirArray of Range values. - unique_ptr rangeArray = TranslateVectorToBuffer( - rangeTupleVector, TranslateRangeTupleToQirRange); + // Translate a PauliID value to its char representation. + char pauliAsCharValue = TranslatePauliToChar(pauliValue); - QirArray* qirRangeArray = CreateQirArray(rangeArray.get(), rangeTupleVector.size()); + // Create an interop array of Pauli values represented as chars. + vector pauliAsCharVector; + TranslateVector(pauliVector, pauliAsCharVector, TranslatePauliToChar); + unique_ptr pauliArray = CreateInteropArray(pauliAsCharVector); - // Create a Result. - Result result = TranslateCharToResult(resultAsCharValue); + // Create an interop range. + unique_ptr rangeValue = CreateInteropRange(rangeTuple); + vector rangeVector; + TranslateVector(rangeTupleVector, rangeVector, TranslateRangeTupleToInteropRange); + unique_ptr rangeArray = CreateInteropArray(rangeVector); - // Create a QirArray of Result values. - unique_ptr resultArray = TranslateVectorToBuffer(resultAsCharVector, TranslateCharToResult); - QirArray* qirResultArray = CreateQirArray(resultArray.get(), resultAsCharVector.size()); - - // Create a QirString. - QirString* qirString = quantum__rt__string_create(stringValue.c_str()); + // Create an interop array of Result values. + unique_ptr resultArray = CreateInteropArray(resultAsCharVector); // Redirect the simulator output from std::cout if the --simulation-output option is present. ostream* simulatorOutputStream = &cout; @@ -234,29 +236,22 @@ int main(int argc, char* argv[]) simulatorOutputStream = &simulationOutputFileStream; } - // Redirect the Q# operation output from std::cout if the --operation-output option is present. - ostream* operationOutputStream = &cout; - ofstream operationOutputFileStream; - if (!operationOutputFileOpt->empty()) - { - operationOutputFileStream.open(operationOutputFile); - operationOutputStream = &operationOutputFileStream; - } - // Run simulation and write the output of the operation to the corresponding stream. - int64_t operationOutput = Quantum__StandaloneSupportedInputs__ExerciseInputs__body( - intValue, doubleValue, result, qirString); + Quantum__StandaloneSupportedInputs__ExerciseInputs( + intValue, + integerArray.get(), + doubleValue, + doubleArray.get(), + boolAsCharValue, + boolArray.get(), + pauliAsCharValue, + pauliArray.get(), + rangeValue.get(), + resultAsCharValue, + resultArray.get(), + stringValue.c_str()); simulatorOutputStream->flush(); - (*operationOutputStream) << operationOutput << endl; - operationOutputStream->flush(); - - // Close opened file buffers; - if (operationOutputFileStream.is_open()) - { - operationOutputFileStream.close(); - } - if (simulationOutputFileStream.is_open()) { simulationOutputFileStream.close(); diff --git a/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.csproj b/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.csproj index 74ef21518f7..2d1679a422d 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.csproj +++ b/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.csproj @@ -1,4 +1,4 @@ - + Exe diff --git a/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs b/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs index 0d6223eadab..1762e75dad5 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs +++ b/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs @@ -1,15 +1,28 @@ namespace Quantum.StandaloneSupportedInputs { + open Microsoft.Quantum.Arrays; open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; + function TautologyPredicate<'T> (input : 'T) : Bool + { + return true; + } + @EntryPoint() - operation ExerciseInputs (intValue : Int, doubleValue : Double, resultValue : Result, stringValue : String) : Int { - Message("Exercise Supported Inputs"); + operation ExerciseInputs (intValue : Int, intArray : Int[], doubleValue : Double, doubleArray : Double[], boolValue : Bool, boolArray : Bool[], pauliValue : Pauli, pauliArray : Pauli[], rangeValue : Range, resultValue : Result, resultArray : Result[], stringValue : String) : Unit { + Message("Exercise Supported Inputs Reference"); Message($"intValue: {intValue}"); + Message($"intArray: {intArray} ({Count(TautologyPredicate, intArray)})"); Message($"doubleValue: {doubleValue}"); + Message($"doubleArray: {doubleArray} ({Count(TautologyPredicate, doubleArray)})"); + Message($"boolValue: {boolValue}"); + Message($"boolArray: {boolArray} ({Count(TautologyPredicate, boolArray)})"); + Message($"pauliValue: {pauliValue}"); + Message($"pauliArray: {pauliArray} ({Count(TautologyPredicate, pauliArray)})"); + Message($"rangeValue: {rangeValue}"); Message($"resultValue: {resultValue}"); + Message($"resultArray: {resultArray} ({Count(TautologyPredicate, resultArray)})"); Message($"stringValue: {stringValue}"); - return 0; } } From e74fe712ce06741085277dda7f017c5b900e54dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Zaragoza=20Cort=C3=A9s?= Date: Mon, 22 Mar 2021 21:08:48 -0700 Subject: [PATCH 2/8] Updated test script. --- src/QirRuntime/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QirRuntime/test.py b/src/QirRuntime/test.py index 2c6e1a8e701..e5c9fdd7b10 100644 --- a/src/QirRuntime/test.py +++ b/src/QirRuntime/test.py @@ -114,6 +114,6 @@ def log(message): " --range-array 1 2 10 5 5 50 10 1 20" +\ " --string-value ASampleString" +\ " --result-value one" +\ - " --result-array one ONE true TRUE 1 zero ZERO false FALSE 0") + " --result-array one ONE 1 zero ZERO 0") print("\n") From 79dfda1749dd87ab0bb6ea0336b87020c978449e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Zaragoza=20Cort=C3=A9s?= Date: Tue, 23 Mar 2021 10:10:58 -0700 Subject: [PATCH 3/8] Added --string-array option. --- .../StandaloneInputReference/qir-driver.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp index f41aa92501b..263068b234a 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp +++ b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp @@ -108,6 +108,11 @@ InteropRange TranslateRangeTupleToInteropRange(RangeTuple rangeTuple) return range; } +const char* TranslateStringToCharBuffer(string s) +{ + return s.c_str(); +} + int main(int argc, char* argv[]) { CLI::App app("QIR Standalone Entry Point Inputs Reference"); @@ -196,6 +201,11 @@ int main(int argc, char* argv[]) string stringValue; app.add_option("--string-value", stringValue, "A String value")->required(); + // Option for a Q# Array type. + vector stringVector; + app.add_option("--string-array", stringVector, "A String array")->required(); + + // With all the options added, parse arguments from the command line. CLI11_PARSE(app, argc, argv); @@ -226,6 +236,11 @@ int main(int argc, char* argv[]) // Create an interop array of Result values. unique_ptr resultArray = CreateInteropArray(resultAsCharVector); + // Create an interop array of String values. + vector stringBufferVector; + TranslateVector(stringVector, stringBufferVector, TranslateStringToCharBuffer); + unique_ptr stringArray = CreateInteropArray(stringBufferVector); + // Redirect the simulator output from std::cout if the --simulation-output option is present. ostream* simulatorOutputStream = &cout; ofstream simulationOutputFileStream; From 53c2f314f6a6078cea0249cecd14b7a3ce59e780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Zaragoza=20Cort=C3=A9s?= Date: Tue, 23 Mar 2021 12:06:56 -0700 Subject: [PATCH 4/8] Addressed Robin's feedback. --- .../StandaloneInputReference/CMakeLists.txt | 2 +- .../StandaloneInputReference/qir-driver.cpp | 43 +++++++++++-------- .../qsharp/qir-standalone-input-reference.qs | 32 +++++++++++--- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt b/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt index 56030445c9c..4d1dd20a3bf 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt +++ b/src/QirRuntime/samples/StandaloneInputReference/CMakeLists.txt @@ -32,7 +32,7 @@ install(TARGETS qir-input-reference-standalone RUNTIME DESTINATION "${CMAKE_BINA include(CTest) add_test( NAME qir-input-reference-standalone - COMMAND qir-input-reference-standalone --int-value 1 --integer-array 1 2 3 4 5 --double-value 0.5 --double-array 0.1 0.2 0.3 0.4 0.5 --bool-value true --bool-array true TRUE false fALSe 1 --pauli-value PauliI --pauli-array PauliI paulix PAULIY PAulIZ --range-value 1 2 10 --range-array 1 2 10 5 5 50 10 1 20 --string-value ASampleString --result-value one --result-array one ONE 1 0 zero ZERO + COMMAND qir-input-reference-standalone --int-value 1 --integer-array 1 2 3 4 5 --double-value 0.5 --double-array 0.1 0.2 0.3 0.4 0.5 --bool-value true --bool-array true TRUE false fALSe 1 --pauli-value PauliI --pauli-array PauliI paulix PAULIY PAulIZ --range-value 1 2 10 --range-array 1 2 10 5 5 50 10 1 20 --string-value ASampleString --result-value one --result-array one ONE 1 0 zero ZERO --string-array StringA StringB StringC ) # set the environment path for loading shared libs the tests are using diff --git a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp index 263068b234a..6fbb6f2ee97 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp +++ b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp @@ -10,6 +10,7 @@ #include "CLI11.hpp" #include "QirContext.hpp" +#include "QirRuntime.hpp" #include "SimFactory.hpp" using namespace Microsoft::Quantum; @@ -19,13 +20,28 @@ struct InteropArray { int64_t Size; void* Data; + + InteropArray(int64_t size, void* data) : + Size(size), + Data(data){} }; +using RangeTuple = tuple; 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)){} }; // This is the function corresponding to the QIR entry-point. @@ -67,48 +83,37 @@ map ResultAsCharMap{ }; template -unique_ptr CreateInteropArray(vector v) +unique_ptr CreateInteropArray(vector& v) { - unique_ptr array(new InteropArray()); - array->Size = v.size(); - array->Data = v.data(); + unique_ptr array(new InteropArray(v.size(), v.data())); return array; } -using RangeTuple = tuple; unique_ptr CreateInteropRange(RangeTuple rangeTuple) { - unique_ptr range(new InteropRange()); - range->Start = get<0>(rangeTuple); - range->Step = get<1>(rangeTuple); - range->End = get<2>(rangeTuple); + unique_ptr range(new InteropRange(rangeTuple)); return range; } -char TranslatePauliToChar(PauliId pauli) +char TranslatePauliToChar(PauliId& pauli) { return static_cast(pauli); } template -void TranslateVector(vectorsourceVector, vector& destinationVector, function translationFunction) +void TranslateVector(vector& sourceVector, vector& destinationVector, function translationFunction) { destinationVector.resize(sourceVector.size()); transform(sourceVector.begin(), sourceVector.end(), destinationVector.begin(), translationFunction); } -InteropRange TranslateRangeTupleToInteropRange(RangeTuple rangeTuple) +InteropRange TranslateRangeTupleToInteropRange(RangeTuple& rangeTuple) { - InteropRange range = { - get<0>(rangeTuple), // Start - get<1>(rangeTuple), // Step - get<2>(rangeTuple) // End - }; - + InteropRange range(rangeTuple); return range; } -const char* TranslateStringToCharBuffer(string s) +const char* TranslateStringToCharBuffer(string& s) { return s.c_str(); } diff --git a/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs b/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs index 1762e75dad5..5125ac0a2cd 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs +++ b/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs @@ -4,6 +4,28 @@ open Microsoft.Quantum.Canon; open Microsoft.Quantum.Intrinsic; + function ArrayToString<'T> (array : 'T[]) : String + { + mutable first = true; + mutable itemsString = "["; + for item in array + { + if (first) + { + set itemsString = itemsString + $"{item}"; + } + else + { + set itemsString = itemsString + $", {item}"; + } + + set first = false; + } + + set itemsString = itemsString + $"]"; + return itemsString; + } + function TautologyPredicate<'T> (input : 'T) : Bool { return true; @@ -13,16 +35,16 @@ operation ExerciseInputs (intValue : Int, intArray : Int[], doubleValue : Double, doubleArray : Double[], boolValue : Bool, boolArray : Bool[], pauliValue : Pauli, pauliArray : Pauli[], rangeValue : Range, resultValue : Result, resultArray : Result[], stringValue : String) : Unit { Message("Exercise Supported Inputs Reference"); Message($"intValue: {intValue}"); - Message($"intArray: {intArray} ({Count(TautologyPredicate, intArray)})"); + Message($"intArray: {ArrayToString(intArray)} ({Count(TautologyPredicate, intArray)})"); Message($"doubleValue: {doubleValue}"); - Message($"doubleArray: {doubleArray} ({Count(TautologyPredicate, doubleArray)})"); + Message($"doubleArray: {ArrayToString(doubleArray)} ({Count(TautologyPredicate, doubleArray)})"); Message($"boolValue: {boolValue}"); - Message($"boolArray: {boolArray} ({Count(TautologyPredicate, boolArray)})"); + Message($"boolArray: {ArrayToString(boolArray)} ({Count(TautologyPredicate, boolArray)})"); Message($"pauliValue: {pauliValue}"); - Message($"pauliArray: {pauliArray} ({Count(TautologyPredicate, pauliArray)})"); + Message($"pauliArray: {ArrayToString(pauliArray)} ({Count(TautologyPredicate, pauliArray)})"); Message($"rangeValue: {rangeValue}"); Message($"resultValue: {resultValue}"); - Message($"resultArray: {resultArray} ({Count(TautologyPredicate, resultArray)})"); + Message($"resultArray: {ArrayToString(resultArray)} ({Count(TautologyPredicate, resultArray)})"); Message($"stringValue: {stringValue}"); } } From 06db22b798c2db5426add7f01f11f0ead14f82a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Zaragoza=20Cort=C3=A9s?= Date: Tue, 23 Mar 2021 12:27:18 -0700 Subject: [PATCH 5/8] Update expectation for Range array. --- .../samples/StandaloneInputReference/qir-driver.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp index 6fbb6f2ee97..303d5795301 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp +++ b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp @@ -107,9 +107,9 @@ void TranslateVector(vector& sourceVector, vector& destinationVector, func transform(sourceVector.begin(), sourceVector.end(), destinationVector.begin(), translationFunction); } -InteropRange TranslateRangeTupleToInteropRange(RangeTuple& rangeTuple) +InteropRange* TranslateRangeTupleToInteropRangePointer(RangeTuple& rangeTuple) { - InteropRange range(rangeTuple); + InteropRange* range = new InteropRange(rangeTuple); return range; } @@ -234,8 +234,8 @@ int main(int argc, char* argv[]) // Create an interop range. unique_ptr rangeValue = CreateInteropRange(rangeTuple); - vector rangeVector; - TranslateVector(rangeTupleVector, rangeVector, TranslateRangeTupleToInteropRange); + vector rangeVector; + TranslateVector(rangeTupleVector, rangeVector, TranslateRangeTupleToInteropRangePointer); unique_ptr rangeArray = CreateInteropArray(rangeVector); // Create an interop array of Result values. From d6e7ea57ba11e12d9c6b5739de3d9cc5e29a8543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Zaragoza=20Cort=C3=A9s?= Date: Tue, 23 Mar 2021 14:45:47 -0700 Subject: [PATCH 6/8] Free vector of allocated pointers. --- .../samples/StandaloneInputReference/qir-driver.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp index 303d5795301..d5a3e934f82 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp +++ b/src/QirRuntime/samples/StandaloneInputReference/qir-driver.cpp @@ -95,6 +95,15 @@ unique_ptr CreateInteropRange(RangeTuple rangeTuple) return range; } +template +void FreePointerVector(vector& v) +{ + for (auto p : v) + { + delete p; + } +} + char TranslatePauliToChar(PauliId& pauli) { return static_cast(pauli); @@ -271,6 +280,7 @@ int main(int argc, char* argv[]) resultArray.get(), stringValue.c_str()); + FreePointerVector(rangeVector); simulatorOutputStream->flush(); if (simulationOutputFileStream.is_open()) { From 2d650845154c068a4d26aad32841408f35b45162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Zaragoza=20Cort=C3=A9s?= Date: Tue, 23 Mar 2021 15:02:09 -0700 Subject: [PATCH 7/8] Update test.py. --- src/QirRuntime/test.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/QirRuntime/test.py b/src/QirRuntime/test.py index e5c9fdd7b10..4e62ea33be7 100644 --- a/src/QirRuntime/test.py +++ b/src/QirRuntime/test.py @@ -100,8 +100,10 @@ def log(message): subprocess.run(test_binary + " ~[skip]", shell = True) log("========= Running samples =========") + sample_binary = os.path.join(install_dir, "qir-input-reference-standalone" + exe_ext) + log(sample_binary) subprocess.run( - "qir-input-reference-standalone" +\ + sample_binary +\ " --int-value 1" +\ " --integer-array 1 2 3 4 5" +\ " --double-value 0.5" +\ @@ -114,6 +116,7 @@ def log(message): " --range-array 1 2 10 5 5 50 10 1 20" +\ " --string-value ASampleString" +\ " --result-value one" +\ - " --result-array one ONE 1 zero ZERO 0") + " --result-array one ONE 1 zero ZERO 0" +\ + " --string-array StringA StringB StringC") print("\n") From e4bf1dddcf752595a5da019bcd0690b1045b8dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Zaragoza=20Cort=C3=A9s?= Date: Tue, 23 Mar 2021 15:06:08 -0700 Subject: [PATCH 8/8] Addressed additional feedback from Robin. --- .../qsharp/qir-standalone-input-reference.qs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs b/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs index 5125ac0a2cd..23908eaa514 100644 --- a/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs +++ b/src/QirRuntime/samples/StandaloneInputReference/qsharp/qir-standalone-input-reference.qs @@ -12,17 +12,16 @@ { if (first) { + set first = false; set itemsString = itemsString + $"{item}"; } else { set itemsString = itemsString + $", {item}"; } - - set first = false; } - set itemsString = itemsString + $"]"; + set itemsString = itemsString + "]"; return itemsString; }