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
5 changes: 3 additions & 2 deletions src/QirRuntime/lib/QIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ compile_from_qir(bridge-qis ${bridge_qis_target})
# create qir-qis-support lib from the C++ sources
#
set(qis_sup_source_files
"intrinsics.cpp"
"intrinsicsMath.cpp"
conditionals.cpp
intrinsics.cpp
intrinsicsMath.cpp
intrinsicsOut.cpp
)

Expand Down
38 changes: 35 additions & 3 deletions src/QirRuntime/lib/QIR/bridge-qis.ll
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ declare void @quantum__qis__y__ctl(%struct.QirArray*, %class.QUBIT*)
declare void @quantum__qis__z__body(%class.QUBIT*)
declare void @quantum__qis__z__ctl(%struct.QirArray*, %class.QUBIT*)

declare void @quantum__qis__message__body(%"struct.QirString"* %str)
declare void @quantum__qis__message__body(%struct.QirString* %str)

;===============================================================================
; quantum.qis namespace implementations
Expand Down Expand Up @@ -284,8 +284,8 @@ define void @__quantum__qis__z__ctl(%Array* %.ctls, %Qubit* %.q) {
;===============================================================================
;
define void @__quantum__qis__message__body(%String* %.str) {
%str = bitcast %String* %.str to %"struct.QirString"*
call void @quantum__qis__message__body(%"struct.QirString"* %str)
%str = bitcast %String* %.str to %struct.QirString*
call void @quantum__qis__message__body(%struct.QirString* %str)
ret void
}

Expand Down Expand Up @@ -437,3 +437,35 @@ define i64 @__quantum__qis__drawrandomint__body(i64 %min, i64 %max) {
%result = call i64 @quantum__qis__drawrandomint__body(i64 %min, i64 %max)
ret i64 %result
}

;===============================================================================
; quantum.qis conditional functions
;
declare void @quantum__qis__applyifelseintrinsic__body(%class.RESULT*, %struct.QirCallable*, %struct.QirCallable*)
declare void @quantum__qis__applyconditionallyintrinsic__body(
%struct.QirArray*, %struct.QirArray*, %struct.QirCallable*, %struct.QirCallable*)

define void @__quantum__qis__applyifelseintrinsic__body(
%Result* %.r, %Callable* %.clb_on_zero, %Callable* %.clb_on_one) {

%r = bitcast %Result* %.r to %class.RESULT*
%clb_on_zero = bitcast %Callable* %.clb_on_zero to %struct.QirCallable*
%clb_on_one = bitcast %Callable* %.clb_on_one to %struct.QirCallable*
call void @quantum__qis__applyifelseintrinsic__body(
%class.RESULT* %r, %struct.QirCallable* %clb_on_zero, %struct.QirCallable* %clb_on_one)
ret void
}

define void @__quantum__qis__applyconditionallyintrinsic__body(
%Array* %.rs1, %Array* %.rs2, %Callable* %.clb_on_equal, %Callable* %.clb_on_different) {

%rs1 = bitcast %Array* %.rs1 to %struct.QirArray*
%rs2 = bitcast %Array* %.rs2 to %struct.QirArray*
%clb_on_equal = bitcast %Callable* %.clb_on_equal to %struct.QirCallable*
%clb_on_different = bitcast %Callable* %.clb_on_different to %struct.QirCallable*
call void @quantum__qis__applyconditionallyintrinsic__body(
%struct.QirArray* %rs1, %struct.QirArray* %rs2,
%struct.QirCallable* %clb_on_equal, %struct.QirCallable* %clb_on_different)
ret void
}

54 changes: 54 additions & 0 deletions src/QirRuntime/lib/QIR/conditionals.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include <cassert>
#include <stdexcept>

#include "quantum__qis.hpp"

#include "QirTypes.hpp"
#include "quantum__rt.hpp"

static void Apply(QirCallable* clb)
{
PTuple argsTuple = quantum__rt__tuple_create(0);
quantum__rt__callable_invoke(clb, argsTuple /*args*/, nullptr /*result*/);
quantum__rt__tuple_update_reference_count(argsTuple, -1);
}

static bool ArraysContainEqualResults(QirArray* rs1, QirArray* rs2)
{
assert(rs1 != nullptr && rs2 != nullptr && rs1->count == rs2->count);
assert(rs1->itemSizeInBytes == sizeof(void*)); // the array should contain pointers to RESULT
assert(rs2->itemSizeInBytes == sizeof(void*)); // the array should contain pointers to RESULT

RESULT** results1 = reinterpret_cast<RESULT**>(rs1->buffer);
RESULT** results2 = reinterpret_cast<RESULT**>(rs2->buffer);
for (int64_t i = 0; i < rs1->count; i++)
{
if (!quantum__rt__result_equal(results1[i], results2[i]))
{
return false;
}
}
return true;
}

extern "C"
{
void quantum__qis__applyifelseintrinsic__body(RESULT* r, QirCallable* clbOnZero, QirCallable* clbOnOne)
{
QirCallable* clbApply = quantum__rt__result_equal(r, quantum__rt__result_zero()) ? clbOnZero : clbOnOne;
Apply(clbApply);
}

void quantum__qis__applyconditionallyintrinsic__body(
QirArray* rs1,
QirArray* rs2,
QirCallable* clbOnAllEqual,
QirCallable* clbOnSomeDifferent)
{
QirCallable* clbApply = ArraysContainEqualResults(rs1, rs2) ? clbOnAllEqual : clbOnSomeDifferent;
Apply(clbApply);
}
}
2 changes: 2 additions & 0 deletions src/QirRuntime/lib/QIR/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
#define QIR_SHARED_API
#endif

// These two globals are used in QIR _directly_ so have to define them outside of the context.
extern "C" QIR_SHARED_API Result ResultOne = nullptr;
extern "C" QIR_SHARED_API Result ResultZero = nullptr;

namespace Microsoft
{
namespace Quantum
Expand Down
4 changes: 2 additions & 2 deletions src/QirRuntime/lib/QIR/delegated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ std::unordered_map<RESULT*, int>& AllocatedResults()

extern "C"
{
Result UseZero()
Result quantum__rt__result_zero()
{
return Microsoft::Quantum::g_context->simulator->UseZero();
}

Result UseOne()
Result quantum__rt__result_one()
{
return Microsoft::Quantum::g_context->simulator->UseOne();
}
Expand Down
31 changes: 19 additions & 12 deletions src/QirRuntime/lib/QIR/quantum__qis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,27 @@ extern "C"
QIR_SHARED_API void quantum__qis__z__body(QUBIT*); // NOLINT
QIR_SHARED_API void quantum__qis__z__ctl(QirArray*, QUBIT*); // NOLINT

QIR_SHARED_API void quantum__qis__message__body(QirString* qstr); // NOLINT
QIR_SHARED_API void quantum__qis__message__body(QirString* qstr); // NOLINT

// Q# Math:
QIR_SHARED_API bool quantum__qis__isnan__body(double d); // NOLINT
QIR_SHARED_API double quantum__qis__infinity__body(); // NOLINT
QIR_SHARED_API bool quantum__qis__isinf__body(double d); // NOLINT
QIR_SHARED_API double quantum__qis__arctan2__body(double y, double x); // NOLINT
QIR_SHARED_API double quantum__qis__sinh__body(double theta); // NOLINT
QIR_SHARED_API double quantum__qis__cosh__body(double theta); // NOLINT
QIR_SHARED_API double quantum__qis__arcsin__body(double theta); // NOLINT
QIR_SHARED_API double quantum__qis__arccos__body(double theta); // NOLINT
QIR_SHARED_API double quantum__qis__arctan__body(double theta); // NOLINT
QIR_SHARED_API bool quantum__qis__isnan__body(double d); // NOLINT
QIR_SHARED_API double quantum__qis__infinity__body(); // NOLINT
QIR_SHARED_API bool quantum__qis__isinf__body(double d); // NOLINT
QIR_SHARED_API double quantum__qis__arctan2__body(double y, double x); // NOLINT
QIR_SHARED_API double quantum__qis__sinh__body(double theta); // NOLINT
QIR_SHARED_API double quantum__qis__cosh__body(double theta); // NOLINT
QIR_SHARED_API double quantum__qis__arcsin__body(double theta); // NOLINT
QIR_SHARED_API double quantum__qis__arccos__body(double theta); // NOLINT
QIR_SHARED_API double quantum__qis__arctan__body(double theta); // NOLINT

QIR_SHARED_API double quantum__qis__ieeeremainder__body(double x, double y); // NOLINT
QIR_SHARED_API int64_t quantum__qis__drawrandomint__body(int64_t minimum, int64_t maximum); // NOLINT
QIR_SHARED_API double quantum__qis__ieeeremainder__body(double x, double y); // NOLINT
QIR_SHARED_API int64_t quantum__qis__drawrandomint__body(int64_t minimum, int64_t maximum); // NOLINT

// Q# ApplyIf:
QIR_SHARED_API void quantum__qis__applyifelseintrinsic__body(RESULT*, QirCallable*, QirCallable*); // NOLINT
QIR_SHARED_API void quantum__qis__applyconditionallyintrinsic__body( // NOLINT
QirArray*,
QirArray*,
QirCallable*,
QirCallable*);
}
4 changes: 4 additions & 0 deletions src/QirRuntime/lib/QIR/quantum__rt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ extern "C"
// becomes 0. The behavior is undefined if the reference count becomes negative.
QIR_SHARED_API void quantum__rt__result_update_reference_count(RESULT*, int32_t); // NOLINT

// Not in the QIR spec right now
QIR_SHARED_API RESULT* quantum__rt__result_one(); // NOLINT
QIR_SHARED_API RESULT* quantum__rt__result_zero(); // NOLINT

// ------------------------------------------------------------------------
// Tuples
// ------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/QirRuntime/test/QIR-static/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ add_custom_target(qir_static_test_lib DEPENDS ${QIR_TESTS_LIBS})
#
add_executable(qir-static-tests
qir-driver.cpp
qir-test-conditionals.cpp
qir-test-math.cpp
qir-test-strings.cpp
qir-test-ouput.cpp
Expand Down
27 changes: 19 additions & 8 deletions src/QirRuntime/test/QIR-static/qir-driver.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include <cassert>
#include <bitset>
#include <cassert>
#include <iostream>
#include <memory>
#include <string>
#include <unordered_set>

#include "CoreTypes.hpp"
#include "QirContext.hpp"
#include "QirTypes.hpp"
#include "QuantumApi_I.hpp"
#include "SimFactory.hpp"
#include "SimulatorStub.hpp"
#include "QirContext.hpp"
#include "QirTypes.hpp"
#include "quantum__rt.hpp"

#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
Expand Down Expand Up @@ -223,8 +223,8 @@ TEST_CASE("QIR: Partial application of a callable", "[qir][qir.partCallable]")
}
#endif

// The Microsoft__Quantum__Testing__QIR__TestControlled__body tests needs proper semantics of X and M, and nothing else.
// The validation is done inside the test and it would return an error code in case of failure.
// The Microsoft__Quantum__Testing__QIR__TestFunctors__body tests needs proper semantics of X and M, and nothing else.
// The validation is done inside the test and it would throw in case of failure.
struct FunctorsTestSimulator : public Microsoft::Quantum::SimulatorStub
{
std::vector<int> qubits;
Expand Down Expand Up @@ -299,13 +299,18 @@ struct FunctorsTestSimulator : public Microsoft::Quantum::SimulatorStub
}
};
FunctorsTestSimulator* g_ctrqapi = nullptr;
extern "C" void Microsoft__Quantum__Testing__QIR__TestControlled__body(); // NOLINT
extern "C" void __quantum__qis__k__body(Qubit q) // NOLINT
static int g_cKCalls = 0;
static int g_cKCallsControlled = 0;
extern "C" void Microsoft__Quantum__Testing__QIR__TestFunctors__body(); // NOLINT
extern "C" void Microsoft__Quantum__Testing__QIR__TestFunctorsNoArgs__body(); // NOLINT
extern "C" void __quantum__qis__k__body(Qubit q) // NOLINT
{
g_cKCalls++;
g_ctrqapi->X(q);
}
extern "C" void __quantum__qis__k__ctl(QirArray* controls, Qubit q) // NOLINT
{
g_cKCallsControlled++;
g_ctrqapi->ControlledX(controls->count, reinterpret_cast<Qubit*>(controls->buffer), q);
}
TEST_CASE("QIR: application of nested controlled functor", "[qir][qir.functor]")
Expand All @@ -314,7 +319,13 @@ TEST_CASE("QIR: application of nested controlled functor", "[qir][qir.functor]")
QirContextScope qirctx(qapi.get(), true /*trackAllocatedObjects*/);
g_ctrqapi = qapi.get();

CHECK_NOTHROW(Microsoft__Quantum__Testing__QIR__TestControlled__body());
CHECK_NOTHROW(Microsoft__Quantum__Testing__QIR__TestFunctors__body());

const int cKCalls = g_cKCalls;
const int cKCallsControlled = g_cKCallsControlled;
CHECK_NOTHROW(Microsoft__Quantum__Testing__QIR__TestFunctorsNoArgs__body());
CHECK(g_cKCalls - cKCalls == 3);
CHECK(g_cKCallsControlled - cKCallsControlled == 5);

g_ctrqapi = nullptr;
}
Loading