From 940eab811fbabe2d97214ed77c36bea452e833ee Mon Sep 17 00:00:00 2001 From: Alex McCaskey Date: Fri, 17 Nov 2023 00:31:47 +0000 Subject: [PATCH] various fixes to restore tests to a working order --- .../cudaq/Optimizer/Dialect/Quake/QuakeOps.td | 2 ++ python/experimental/cudaq/_query_gpu.py | 6 +++- .../experimental/cudaq/kernel/ast_bridge.py | 10 ++++-- .../cudaq/kernel/kernel_builder.py | 36 +++++++++++++------ python/experimental/cudaq/kernel/qubit_qis.py | 6 ++-- .../runtime/mlir/py_register_dialects.cpp | 6 ++++ .../runtime/utils/PyRemoteRESTQPU.cpp | 5 +++ .../tests/ast/test_library_kernels.py | 12 +++++-- .../tests/builder/test_kernel_builder.py | 8 ++--- .../tests/eager/test_user_custom_operation.py | 8 ++--- python/experimental/tests/mlir/adjoint.py | 4 +-- python/experimental/tests/mlir/conditional.py | 36 ++++++++++--------- python/experimental/tests/mlir/control.py | 6 ++-- .../tests/mlir/lit.site.cfg.py.in | 2 +- python/experimental/tests/mlir/measure.py | 18 +++++----- python/experimental/tests/mlir/swap.py | 2 +- runtime/common/BaseRemoteRESTQPU.h | 6 ++++ 17 files changed, 112 insertions(+), 61 deletions(-) diff --git a/include/cudaq/Optimizer/Dialect/Quake/QuakeOps.td b/include/cudaq/Optimizer/Dialect/Quake/QuakeOps.td index 479006d3c7..99a186fb78 100644 --- a/include/cudaq/Optimizer/Dialect/Quake/QuakeOps.td +++ b/include/cudaq/Optimizer/Dialect/Quake/QuakeOps.td @@ -831,6 +831,8 @@ def ExpPauliOp : QuakeOp<"exp_pauli"> { }]; } +// [RFC]: +// Applying arbitrary unitaries is a separate feature and needs to be removed from the prototype. def UnitaryOp : QuakeOp<"unitary", [AttrSizedOperandSegments]> { let summary = "General unitary operation specified by constant unitary matrix data"; let description = [{ diff --git a/python/experimental/cudaq/_query_gpu.py b/python/experimental/cudaq/_query_gpu.py index 3ca97a6216..c678b5b2fe 100644 --- a/python/experimental/cudaq/_query_gpu.py +++ b/python/experimental/cudaq/_query_gpu.py @@ -13,7 +13,11 @@ # Install directory is wherever this script is and up one directory install_dir = Path(__file__).parent.parent.resolve() - +# [RFC]: +# This file should not be here; it is from an earlier version and has since been removed. +# Double check that the content of the following PR is properly incorporated: +# https://github.com/NVIDIA/cuda-quantum/pull/877 +# def is_gpu_available(): try: gpu_list = subprocess.check_output(["nvidia-smi", "-L"], diff --git a/python/experimental/cudaq/kernel/ast_bridge.py b/python/experimental/cudaq/kernel/ast_bridge.py index 127a14c41e..a36034ed05 100644 --- a/python/experimental/cudaq/kernel/ast_bridge.py +++ b/python/experimental/cudaq/kernel/ast_bridge.py @@ -453,6 +453,8 @@ def isQuantumTy(ty): globalKernelRegistry[node.name] = f self.symbolTable.clear() + # [RFC]: + # Examine if we really want to extend Python with a dedicated syntax. def visit_Lambda(self, node): """ Map a lambda expression in a CUDA Quantum kernel to a CC Lambda (a Value of `cc.callable` type @@ -813,9 +815,11 @@ def bodyBuilder(iterVar): i1Ty = self.getIntegerType(1) resTy = i1Ty if quake.RefType.isinstance( qubit.type) else cc.StdvecType.get(self.ctx, i1Ty) - self.pushValue( - opCtor(resTy, [], [qubit], - registerName=self.currentAssignVariableName).result) + measTy = quake.MeasureType.get(self.ctx) if quake.RefType.isinstance( + qubit.type) else cc.StdvecType.get(self.ctx, quake.MeasureType.get(self.ctx)) + measureResult = opCtor(measTy, [], [qubit], + registerName=self.currentAssignVariableName).result + self.pushValue(quake.DiscriminateOp(resTy, measureResult).result) return if node.func.id == 'swap': diff --git a/python/experimental/cudaq/kernel/kernel_builder.py b/python/experimental/cudaq/kernel/kernel_builder.py index 4b302b27d8..a171131f83 100644 --- a/python/experimental/cudaq/kernel/kernel_builder.py +++ b/python/experimental/cudaq/kernel/kernel_builder.py @@ -575,15 +575,17 @@ def mz(self, target, regName=None): i1Ty = IntegerType.get_signless(1, context=self.ctx) qubitTy = target.mlirValue.type retTy = i1Ty + measTy = quake.MeasureType.get(self.ctx) stdvecTy = cc.StdvecType.get(self.ctx, i1Ty) if quake.VeqType.isinstance(target.mlirValue.type): retTy = stdvecTy - + measTy = cc.StdvecType.get(self.ctx, measTy) res = quake.MzOp( - retTy, [], [target.mlirValue], + measTy, [], [target.mlirValue], registerName=StringAttr.get(regName, context=self.ctx) if regName is not None else '') - return self.__createQuakeValue(res.result) + disc = quake.DiscriminateOp(retTy, res) + return self.__createQuakeValue(disc.result) def mx(self, target, regName=None): """ @@ -618,13 +620,17 @@ def mx(self, target, regName=None): i1Ty = IntegerType.get_signless(1, context=self.ctx) qubitTy = target.mlirValue.type retTy = i1Ty + measTy = quake.MeasureType.get(self.ctx) stdvecTy = cc.StdvecType.get(self.ctx, i1Ty) if quake.VeqType.isinstance(target.mlirValue.type): retTy = stdvecTy - res = quake.MxOp(retTy, [], [target.mlirValue], - registerName=StrAttr.get(regName, context=self.ctx) - if regName is not None else '') - return self.__createQuakeValue(res.result) + measTy = cc.StdvecType.get(self.ctx, measTy) + res = quake.MxOp( + measTy, [], [target.mlirValue], + registerName=StringAttr.get(regName, context=self.ctx) + if regName is not None else '') + disc = quake.DiscriminateOp(retTy, res) + return self.__createQuakeValue(disc.result) def my(self, target, regName=None): """ @@ -659,13 +665,17 @@ def my(self, target, regName=None): i1Ty = IntegerType.get_signless(1, context=self.ctx) qubitTy = target.mlirValue.type retTy = i1Ty + measTy = quake.MeasureType.get(self.ctx) stdvecTy = cc.StdvecType.get(self.ctx, i1Ty) if quake.VeqType.isinstance(target.mlirValue.type): retTy = stdvecTy - res = quake.MyOp(retTy, [], [target.mlirValue], - registerName=StrAttr.get(regName, context=self.ctx) - if regName is not None else '') - return self.__createQuakeValue(res.result) + measTy = cc.StdvecType.get(self.ctx, measTy) + res = quake.MyOp( + measTy, [], [target.mlirValue], + registerName=StringAttr.get(regName, context=self.ctx) + if regName is not None else '') + disc = quake.DiscriminateOp(retTy, res) + return self.__createQuakeValue(disc.result) def adjoint(self, otherKernel, *args): """ @@ -798,6 +808,10 @@ def then_function(): if not IntegerType.isinstance(conditional.type): raise RuntimeError("c_if conditional must be an i1 type.") + # [RFC]: + # The register names in the conditional.py tests need to be double checked; + # The code here may need to be adjusted to reflect the additional + # quake.discriminate conversion of the measurement. if isinstance(conditional.owner.opview, quake.MzOp): regName = StringAttr( conditional.owner.attributes['registerName']).value diff --git a/python/experimental/cudaq/kernel/qubit_qis.py b/python/experimental/cudaq/kernel/qubit_qis.py index 4b629fbaca..57601904dd 100644 --- a/python/experimental/cudaq/kernel/qubit_qis.py +++ b/python/experimental/cudaq/kernel/qubit_qis.py @@ -111,7 +111,7 @@ def __call__(cls, *args): cudaq_runtime.applyQuantumOperation(opName, parameters, [], qubitIds, False, - SpinOperator(), unitary) + SpinOperator()) return # Not a custom unitary, handle basic quantum operation, @@ -156,7 +156,7 @@ def ctrl(cls, *args): cudaq_runtime.applyQuantumOperation(opName, parameters, controls, targets, False, - SpinOperator(), unitary) + SpinOperator()) for q in quantumArguments: if isinstance(q, qubit) and q.is_negated(): x()(q) @@ -190,7 +190,7 @@ def adj(cls, *args): cudaq_runtime.applyQuantumOperation(opName, [-1 * p for p in parameters], [], qubitIds, False, - SpinOperator(), unitary) + SpinOperator()) return # Not a custom unitary, handle basic quantum operation, diff --git a/python/experimental/runtime/mlir/py_register_dialects.cpp b/python/experimental/runtime/mlir/py_register_dialects.cpp index 6219e1c088..8de3606131 100644 --- a/python/experimental/runtime/mlir/py_register_dialects.cpp +++ b/python/experimental/runtime/mlir/py_register_dialects.cpp @@ -55,6 +55,12 @@ void registerQuakeDialectAndTypes(py::module &m) { return wrap(quake::RefType::get(unwrap(ctx))); }); + mlir_type_subclass(quakeMod, "MeasureType", [](MlirType type) { + return unwrap(type).isa(); + }).def_classmethod("get", [](py::object cls, MlirContext ctx) { + return wrap(quake::MeasureType::get(unwrap(ctx))); + }); + mlir_type_subclass( quakeMod, "VeqType", [](MlirType type) { return unwrap(type).isa(); }) diff --git a/python/experimental/runtime/utils/PyRemoteRESTQPU.cpp b/python/experimental/runtime/utils/PyRemoteRESTQPU.cpp index e6b530eae4..9890d8f92b 100644 --- a/python/experimental/runtime/utils/PyRemoteRESTQPU.cpp +++ b/python/experimental/runtime/utils/PyRemoteRESTQPU.cpp @@ -8,6 +8,11 @@ #include "common/BaseRemoteRESTQPU.h" #include "common/RuntimeMLIRCommonImpl.h" +// [RFC]: +// The RemoteRESTQPU implementation that is now split across several files needs to be examined carefully. +// What used to be in /runtime/cudaq/platform/default/rest/RemoteRESTQPU.cpp is now largely in +// the header /runtime/common/BaseRemoteRESTQPU.h [status 11/18/23], but some updates were missed; +// The updatePassPipeline interface method in the ServerHelper, for example, was not invoked at all. using namespace mlir; extern "C" void deviceCodeHolderAdd(const char *, const char *); diff --git a/python/experimental/tests/ast/test_library_kernels.py b/python/experimental/tests/ast/test_library_kernels.py index aa23d5056e..d625f4e5b5 100644 --- a/python/experimental/tests/ast/test_library_kernels.py +++ b/python/experimental/tests/ast/test_library_kernels.py @@ -12,10 +12,15 @@ import cudaq -cudaq.enable_jit() -from cudaq.lib import fermionic_swap, givens +# [RFC]: +# FIXME: Why does having this here instead of inside the respective test cause issues? +# cudaq.enable_jit() +# from cudaq.lib import fermionic_swap, givens def test_fswap_lib_kernel(): + cudaq.enable_jit() + from cudaq.lib import fermionic_swap + angle = 0.2 c = np.cos(angle/2) si = np.sin(angle/2) @@ -31,6 +36,9 @@ def bar(angle:float): assert np.isclose(np.abs(ss_01[2] - (np.exp(1j * angle / 2.0) * c)), 0.0, 1e-3) def test_givens_lib_kernel(): + cudaq.enable_jit() + from cudaq.lib import givens + angle = 0.2 c = np.cos(angle) si = np.sin(angle) diff --git a/python/experimental/tests/builder/test_kernel_builder.py b/python/experimental/tests/builder/test_kernel_builder.py index e31d956cf4..bff54de658 100644 --- a/python/experimental/tests/builder/test_kernel_builder.py +++ b/python/experimental/tests/builder/test_kernel_builder.py @@ -359,13 +359,13 @@ def test_fermionic_swap_op(): test_01.x(qubits_01[0]) test_01.fermionic_swap(angle, qubits_01[0], qubits_01[1]) ss_01 = cudaq.get_state(test_01) - assert np.isclose(np.abs(ss_01[1] - (-1j * np.exp(1j * angle / 2.0) * s)), 0.0, 1e-3) - assert np.isclose(np.abs(ss_01[2] - (np.exp(1j * angle / 2.0) * c)), 0.0, 1e-3) + assert np.isclose(np.abs(ss_01[1] - (-1j * np.exp(1j * angle / 2.0) * s)), 0.0, atol=1e-3) + assert np.isclose(np.abs(ss_01[2] - (np.exp(1j * angle / 2.0) * c)), 0.0, atol=1e-3) test_10 = cudaq.make_kernel() qubits_10 = test_10.qalloc(2) test_10.x(qubits_10[1]) test_10.fermionic_swap(angle, qubits_10[0], qubits_10[1]) ss_10 = cudaq.get_state(test_10) - assert np.isclose(np.abs(ss_10[1] - (np.exp(1j * angle / 2.0) * c)), 0.0, 1e-3) - assert np.isclose(np.abs(ss_10[2] - (-1j * np.exp(1j * angle / 2.0) * s)), 0.0, 1e-3) + assert np.isclose(np.abs(ss_10[1] - (np.exp(1j * angle / 2.0) * c)), 0.0, atol=1e-3) + assert np.isclose(np.abs(ss_10[2] - (-1j * np.exp(1j * angle / 2.0) * s)), 0.0, atol=1e-3) diff --git a/python/experimental/tests/eager/test_user_custom_operation.py b/python/experimental/tests/eager/test_user_custom_operation.py index 006aaa011c..0bf7088e00 100644 --- a/python/experimental/tests/eager/test_user_custom_operation.py +++ b/python/experimental/tests/eager/test_user_custom_operation.py @@ -120,12 +120,12 @@ def kernel(angle:float, flag:bool): print(kernel) ss_01 = cudaq.get_state(kernel, angle, False) - assert np.isclose(ss_01[1], -s, 1e-3) - assert np.isclose(ss_01[2], c, 1e-3) + assert np.isclose(ss_01[1], -s, atol=1e-3) + assert np.isclose(ss_01[2], c, atol=1e-3) ss_10 = cudaq.get_state(kernel, angle, True) - assert np.isclose(ss_10[1], c, 1e-3) - assert np.isclose(ss_10[2], s, 1e-3) + assert np.isclose(ss_10[1], c, atol=1e-3) + assert np.isclose(ss_10[2], s, atol=1e-3) def test_parameterized_op4(): diff --git a/python/experimental/tests/mlir/adjoint.py b/python/experimental/tests/mlir/adjoint.py index d29a6cda87..40a3e19c48 100644 --- a/python/experimental/tests/mlir/adjoint.py +++ b/python/experimental/tests/mlir/adjoint.py @@ -237,7 +237,7 @@ def test_sample_adjoint_qubit(): # CHECK: quake.x %[[VAL_0]] : (!quake.ref) -> () # CHECK: call @__nvqpp__mlirgen____nvqppBuilderKernel_{{.*}}(%[[VAL_0]]) : (!quake.ref) -> () # CHECK: quake.apply @__nvqpp__mlirgen____nvqppBuilderKernel_{{.*}} %[[VAL_0]] : (!quake.ref) -> () -# CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] name "" : (!quake.ref) -> i1 +# CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] name "" : (!quake.ref) -> !quake.measure # CHECK: return # CHECK: } @@ -297,7 +297,7 @@ def test_sample_adjoint_qreg(): # CHECK: } {invariant} # CHECK: call @__nvqpp__mlirgen____nvqppBuilderKernel_{{.*}}(%[[VAL_3]]) : (!quake.veq) -> () # CHECK: quake.apply @__nvqpp__mlirgen____nvqppBuilderKernel_{{.*}} %[[VAL_3]] : (!quake.veq) -> () -# CHECK: %[[VAL_13:.*]] = quake.mz %0 name "" : (!quake.veq) -> !cc.stdvec +# CHECK: %[[VAL_13:.*]] = quake.mz %0 name "" : (!quake.veq) -> !cc.stdvec # CHECK: return # CHECK: } diff --git a/python/experimental/tests/mlir/conditional.py b/python/experimental/tests/mlir/conditional.py index 7a36188c67..907e8010fa 100644 --- a/python/experimental/tests/mlir/conditional.py +++ b/python/experimental/tests/mlir/conditional.py @@ -54,27 +54,28 @@ def test_function(): # CHECK: %[[VAL_6:.*]] = quake.extract_ref %[[VAL_5]][0] : (!quake.veq<2>) -> !quake.ref # CHECK: %[[VAL_7:.*]] = quake.extract_ref %[[VAL_5]][1] : (!quake.veq<2>) -> !quake.ref # CHECK: quake.x %[[VAL_6]] : (!quake.ref) -> () -# CHECK: %[[VAL_8:.*]] = quake.mz %[[VAL_6]] name "measurement_" : (!quake.ref) -> i1 -# CHECK: cc.if(%[[VAL_8]]) { +# CHECK: %[[VAL_8:.*]] = quake.mz %[[VAL_6]] name "measurement_" : (!quake.ref) -> !quake.measure +# CHECK: %[[VAL_9:.*]] = quake.discriminate %[[VAL_8]] : (!quake.measure) -> i1 +# CHECK: cc.if(%[[VAL_9]]) { # CHECK: quake.x %[[VAL_7]] : (!quake.ref) -> () -# CHECK: %[[VAL_9:.*]] = quake.mz %[[VAL_7]] name "" : (!quake.ref) -> i1 +# CHECK: %[[VAL_10:.*]] = quake.mz %[[VAL_7]] name "" : (!quake.ref) -> !quake.measure # CHECK: } -# CHECK: %[[VAL_10:.*]] = cc.loop while ((%[[VAL_11:.*]] = %[[VAL_2]]) -> (i64)) { -# CHECK: %[[VAL_12:.*]] = arith.cmpi slt, %[[VAL_11]], %[[VAL_0]] : i64 -# CHECK: cc.condition %[[VAL_12]](%[[VAL_11]] : i64) +# CHECK: %[[VAL_11:.*]] = cc.loop while ((%[[VAL_12:.*]] = %[[VAL_2]]) -> (i64)) { +# CHECK: %[[VAL_13:.*]] = arith.cmpi slt, %[[VAL_12]], %[[VAL_0]] : i64 +# CHECK: cc.condition %[[VAL_13]](%[[VAL_12]] : i64) # CHECK: } do { -# CHECK: ^bb0(%[[VAL_13:.*]]: i64): -# CHECK: %[[VAL_14:.*]] = quake.extract_ref %[[VAL_5]][%[[VAL_13]]] : (!quake.veq<2>, i64) -> !quake.ref -# CHECK: quake.x %[[VAL_14]] : (!quake.ref) -> () -# CHECK: cc.continue %[[VAL_13]] : i64 +# CHECK: ^bb0(%[[VAL_14:.*]]: i64): +# CHECK: %[[VAL_15:.*]] = quake.extract_ref %[[VAL_5]][%[[VAL_14]]] : (!quake.veq<2>, i64) -> !quake.ref +# CHECK: quake.x %[[VAL_15]] : (!quake.ref) -> () +# CHECK: cc.continue %[[VAL_14]] : i64 # CHECK: } step { -# CHECK: ^bb0(%[[VAL_15:.*]]: i64): -# CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_15]], %[[VAL_1]] : i64 -# CHECK: cc.continue %[[VAL_16]] : i64 +# CHECK: ^bb0(%[[VAL_16:.*]]: i64): +# CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_16]], %[[VAL_1]] : i64 +# CHECK: cc.continue %[[VAL_17]] : i64 # CHECK: } {invariant} -# CHECK: cc.if(%[[VAL_8]]) { +# CHECK: cc.if(%[[VAL_9]]) { # CHECK: quake.x %[[VAL_7]] : (!quake.ref) -> () -# CHECK: %[[VAL_17:.*]] = quake.mz %[[VAL_7]] name "" : (!quake.ref) -> i1 +# CHECK: %[[VAL_18:.*]] = quake.mz %[[VAL_7]] name "" : (!quake.ref) -> !quake.measure # CHECK: } # CHECK: return # CHECK: } @@ -114,8 +115,9 @@ def then_function(): # CHECK-LABEL: func.func @__nvqpp__mlirgen____nvqppBuilderKernel_{{.*}}() attributes {"cudaq-entrypoint"} { # CHECK: %[[VAL_0:.*]] = quake.alloca !quake.ref # CHECK: quake.x %[[VAL_0]] : (!quake.ref) -> () -# CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] name "auto_register_0" : (!quake.ref) -> i1 -# CHECK: cc.if(%[[VAL_1]]) { +# CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] name "" : (!quake.ref) -> !quake.measure +# CHECK: %[[VAL_2:.*]] = quake.discriminate %[[VAL_1]] : (!quake.measure) -> i1 +# CHECK: cc.if(%[[VAL_2]]) { # CHECK: quake.x %[[VAL_0]] : (!quake.ref) -> () # CHECK: } # CHECK: return diff --git a/python/experimental/tests/mlir/control.py b/python/experimental/tests/mlir/control.py index 2a3b253022..88adbe7528 100644 --- a/python/experimental/tests/mlir/control.py +++ b/python/experimental/tests/mlir/control.py @@ -283,7 +283,7 @@ def test_sample_control_qubit_args(): # CHECK: quake.h %[[VAL_1]] : (!quake.ref) -> () # CHECK: quake.apply @__nvqpp__mlirgen____nvqppBuilderKernel_{{.*\[}}%[[VAL_1]]] %[[VAL_0]] : (!quake.ref, !quake.ref) -> () # CHECK: quake.h %[[VAL_1]] : (!quake.ref) -> () -# CHECK: %[[VAL_2:.*]] = quake.mz %[[VAL_1]] name "" : (!quake.ref) -> i1 +# CHECK: %[[VAL_2:.*]] = quake.mz %[[VAL_1]] name "" : (!quake.ref) -> !quake.measure # CHECK: return # CHECK: } @@ -338,7 +338,7 @@ def test_sample_control_qreg_args(): # CHECK: quake.x %[[VAL_7]] : (!quake.ref) -> () # CHECK: quake.x %[[VAL_6]] : (!quake.ref) -> () # CHECK: quake.apply @__nvqpp__mlirgen____nvqppBuilderKernel_{{.*}}{{\[}}%[[VAL_5]]] %[[VAL_6]] : (!quake.veq<2>, !quake.ref) -> () -# CHECK: %[[VAL_19:.*]] = quake.mz %[[VAL_6]] name "" : (!quake.ref) -> i1 +# CHECK: %[[VAL_19:.*]] = quake.mz %[[VAL_6]] name "" : (!quake.ref) -> !quake.measure # CHECK: return # CHECK: } @@ -394,7 +394,7 @@ def test_sample_apply_call_control(): # CHECK: quake.h %[[VAL_1]] : (!quake.ref) -> () # CHECK: quake.apply @__nvqpp__mlirgen____nvqppBuilderKernel_{{.*}}{{\[}}%[[VAL_1]]] %[[VAL_0]] : (!quake.ref, !quake.ref) -> () # CHECK: quake.h %[[VAL_1]] : (!quake.ref) -> () -# CHECK: %[[VAL_2:.*]] = quake.mz %[[VAL_1]] name "" : (!quake.ref) -> i1 +# CHECK: %[[VAL_2:.*]] = quake.mz %[[VAL_1]] name "" : (!quake.ref) -> !quake.measure # CHECK: return # CHECK: } diff --git a/python/experimental/tests/mlir/lit.site.cfg.py.in b/python/experimental/tests/mlir/lit.site.cfg.py.in index ce61503fba..2fa463506c 100644 --- a/python/experimental/tests/mlir/lit.site.cfg.py.in +++ b/python/experimental/tests/mlir/lit.site.cfg.py.in @@ -30,4 +30,4 @@ import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@CUDAQ_SOURCE_DIR@/python/mlir/tests/mlir/lit.cfg.py") +lit_config.load_config(config, "@CUDAQ_SOURCE_DIR@/python/experimental/tests/mlir/lit.cfg.py") diff --git a/python/experimental/tests/mlir/measure.py b/python/experimental/tests/mlir/measure.py index 03c35a9c9f..201f1819be 100644 --- a/python/experimental/tests/mlir/measure.py +++ b/python/experimental/tests/mlir/measure.py @@ -42,12 +42,12 @@ def test_kernel_measure_1q(): # CHECK: %[[VAL_2:.*]] = quake.alloca !quake.veq<2> # CHECK: %[[VAL_3:.*]] = quake.extract_ref %[[VAL_2]][0] : (!quake.veq<2>) -> !quake.ref # CHECK: %[[VAL_4:.*]] = quake.extract_ref %[[VAL_2]][1] : (!quake.veq<2>) -> !quake.ref -# CHECK: %[[VAL_5:.*]] = quake.mx %[[VAL_3]] name "" : (!quake.ref) -> i1 -# CHECK: %[[VAL_6:.*]] = quake.mx %[[VAL_4]] name "" : (!quake.ref) -> i1 -# CHECK: %[[VAL_7:.*]] = quake.my %[[VAL_3]] name "" : (!quake.ref) -> i1 -# CHECK: %[[VAL_8:.*]] = quake.my %[[VAL_4]] name "" : (!quake.ref) -> i1 -# CHECK: %[[VAL_9:.*]] = quake.mz %[[VAL_3]] name "" : (!quake.ref) -> i1 -# CHECK: %[[VAL_10:.*]] = quake.mz %[[VAL_4]] name "" : (!quake.ref) -> i1 +# CHECK: %[[VAL_5:.*]] = quake.mx %[[VAL_3]] name "" : (!quake.ref) -> !quake.measure +# CHECK: %[[VAL_6:.*]] = quake.mx %[[VAL_4]] name "" : (!quake.ref) -> !quake.measure +# CHECK: %[[VAL_7:.*]] = quake.my %[[VAL_3]] name "" : (!quake.ref) -> !quake.measure +# CHECK: %[[VAL_8:.*]] = quake.my %[[VAL_4]] name "" : (!quake.ref) -> !quake.measure +# CHECK: %[[VAL_9:.*]] = quake.mz %[[VAL_3]] name "" : (!quake.ref) -> !quake.measure +# CHECK: %[[VAL_10:.*]] = quake.mz %[[VAL_4]] name "" : (!quake.ref) -> !quake.measure # CHECK: return # CHECK: } @@ -70,9 +70,9 @@ def test_kernel_measure_qreg(): # CHECK-LABEL: func.func @__nvqpp__mlirgen____nvqppBuilderKernel_{{.*}}() attributes {"cudaq-entrypoint"} { # CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<3> -# CHECK: %[[VAL_1:.*]] = quake.mx %[[VAL_0]] name "" : (!quake.veq<3>) -> !cc.stdvec -# CHECK: %[[VAL_2:.*]] = quake.my %[[VAL_0]] name "" : (!quake.veq<3>) -> !cc.stdvec -# CHECK: %[[VAL_3:.*]] = quake.mz %[[VAL_0]] name "" : (!quake.veq<3>) -> !cc.stdvec +# CHECK: %[[VAL_1:.*]] = quake.mx %[[VAL_0]] name "" : (!quake.veq<3>) -> !cc.stdvec +# CHECK: %[[VAL_2:.*]] = quake.my %[[VAL_0]] name "" : (!quake.veq<3>) -> !cc.stdvec +# CHECK: %[[VAL_3:.*]] = quake.mz %[[VAL_0]] name "" : (!quake.veq<3>) -> !cc.stdvec # CHECK: return # CHECK: } diff --git a/python/experimental/tests/mlir/swap.py b/python/experimental/tests/mlir/swap.py index 5a607b6805..00d2e4ee4b 100644 --- a/python/experimental/tests/mlir/swap.py +++ b/python/experimental/tests/mlir/swap.py @@ -38,7 +38,7 @@ def test_swap_2q(): # CHECK: %[[VAL_2:.*]] = quake.extract_ref %[[VAL_0]][1] : (!quake.veq<2>) -> !quake.ref # CHECK: quake.x %[[VAL_1]] : (!quake.ref) -> () # CHECK: quake.swap %[[VAL_1]], %[[VAL_2]] : (!quake.ref, !quake.ref) -> () -# CHECK: %[[VAL_3:.*]] = quake.mz %[[VAL_0]] name "" : (!quake.veq<2>) -> !cc.stdvec +# CHECK: %[[VAL_3:.*]] = quake.mz %[[VAL_0]] name "" : (!quake.veq<2>) -> !cc.stdvec # CHECK: return # CHECK: } diff --git a/runtime/common/BaseRemoteRESTQPU.h b/runtime/common/BaseRemoteRESTQPU.h index 39198ed05b..ae9fe369ae 100644 --- a/runtime/common/BaseRemoteRESTQPU.h +++ b/runtime/common/BaseRemoteRESTQPU.h @@ -301,6 +301,7 @@ class BaseRemoteRESTQPU : public cudaq::QPU { // Create the ServerHelper for this QPU and give it the backend config serverHelper = cudaq::registry::get(qpuName); serverHelper->initialize(backendConfig); + serverHelper->updatePassPipeline(platformPath, passPipelineConfig); // Give the server helper to the executor executor->setServerHelper(serverHelper.get()); @@ -375,6 +376,10 @@ class BaseRemoteRESTQPU : public cudaq::QPU { throw std::runtime_error( "Remote rest platform failed to add passes to pipeline (" + errMsg + ")."); + if (disableMLIRthreading || enablePrintMLIREachPass) + moduleOpIn.getContext()->disableMultithreading(); + if (enablePrintMLIREachPass) + pm.enableIRPrinting(); if (failed(pm.run(moduleOpIn))) throw std::runtime_error("Remote rest platform Quake lowering failed."); }; @@ -470,6 +475,7 @@ class BaseRemoteRESTQPU : public cudaq::QPU { cleanupContext(contextPtr); return codes; } + /// @brief Launch the kernel. Extract the Quake code and lower to /// the representation required by the targeted backend. Handle all pertinent /// modifications for the execution context as well as async or sync