From e436e95708329584602cc40254f26b3e18fe7b6d Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Thu, 14 Nov 2024 18:24:36 -0800 Subject: [PATCH 01/47] Add missing passes for translation to OpenQasm2 Signed-off-by: Anna Gringauze --- include/cudaq/Optimizer/Dialect/CC/CCOps.td | 22 +++- lib/Frontend/nvqpp/ConvertExpr.cpp | 6 +- lib/Optimizer/Builder/Intrinsics.cpp | 9 +- lib/Optimizer/CodeGen/Pipelines.cpp | 10 ++ lib/Optimizer/Dialect/CC/CCOps.cpp | 59 ---------- .../Transforms/DecompositionPatterns.cpp | 108 ++++++++++++++++++ .../Transforms/GetConcreteMatrix.cpp | 2 + .../default/rest/helpers/braket/braket.yml | 2 +- targettests/braket/custom_operation_adj.cpp | 1 + targettests/braket/custom_operation_basic.cpp | 1 + targettests/braket/graph_coloring-1.cpp | 1 + targettests/braket/graph_coloring.cpp | 1 + targettests/braket/sudoku_2x2-1.cpp | 80 +------------ targettests/braket/sudoku_2x2-bit_names.cpp | 104 +---------------- targettests/braket/sudoku_2x2-reg_name.cpp | 80 +------------ targettests/braket/sudoku_2x2.cpp | 79 +------------ .../execution/custom_operation_adj.cpp | 15 ++- .../execution/custom_operation_basic.cpp | 15 ++- targettests/execution/graph_coloring-1.cpp | 3 +- targettests/execution/graph_coloring.cpp | 3 +- .../DecompositionPatterns/RxAdjToRx.qke | 25 ++++ .../DecompositionPatterns/RyAdjToRy.qke | 25 ++++ .../DecompositionPatterns/RzAdjToRz.qke | 25 ++++ .../translate_openqasm2_adj_rotations.cpp | 61 ++++++++++ .../translate_openqasm2_custom_operation.cpp | 59 ++++++++++ 25 files changed, 377 insertions(+), 419 deletions(-) create mode 120000 targettests/braket/custom_operation_adj.cpp create mode 120000 targettests/braket/custom_operation_basic.cpp create mode 120000 targettests/braket/graph_coloring-1.cpp create mode 120000 targettests/braket/graph_coloring.cpp mode change 100644 => 120000 targettests/braket/sudoku_2x2-1.cpp mode change 100644 => 120000 targettests/braket/sudoku_2x2-bit_names.cpp mode change 100644 => 120000 targettests/braket/sudoku_2x2-reg_name.cpp mode change 100644 => 120000 targettests/braket/sudoku_2x2.cpp create mode 100644 test/Transforms/DecompositionPatterns/RxAdjToRx.qke create mode 100644 test/Transforms/DecompositionPatterns/RyAdjToRy.qke create mode 100644 test/Transforms/DecompositionPatterns/RzAdjToRz.qke create mode 100644 test/Translate/translate_openqasm2_adj_rotations.cpp create mode 100644 test/Translate/translate_openqasm2_custom_operation.cpp diff --git a/include/cudaq/Optimizer/Dialect/CC/CCOps.td b/include/cudaq/Optimizer/Dialect/CC/CCOps.td index a58e3d403d..71e1702a97 100644 --- a/include/cudaq/Optimizer/Dialect/CC/CCOps.td +++ b/include/cudaq/Optimizer/Dialect/CC/CCOps.td @@ -10,6 +10,7 @@ #define CUDAQ_OPTIMIZER_DIALECT_CC_OPS include "mlir/Interfaces/InferTypeOpInterface.td" +include "mlir/IR/SymbolInterfaces.td" include "cudaq/Optimizer/Dialect/Common/Traits.td" include "cudaq/Optimizer/Dialect/CC/CCDialect.td" include "cudaq/Optimizer/Dialect/CC/CCInterfaces.td" @@ -913,17 +914,36 @@ def cc_GlobalOp : CCOp<"global", [IsolatedFromAbove, Symbol]> { TypeAttr:$global_type, StrAttr:$sym_name, OptionalAttr:$value, + OptionalAttr:$sym_visibility, UnitAttr:$constant, UnitAttr:$external ); - let hasCustomAssemblyFormat = 1; + let assemblyFormat = [{ + ( `external` $external^ )? ( `constant` $constant^ )? + $sym_name `(`$value`)` `:` qualified($global_type) attr-dict + }]; + + let builders = [ + OpBuilder<(ins + "mlir::Type":$type, "mlir::StringRef":$name, + "mlir::Attribute":$value, "bool":$constant, "bool":$external), [{ + return build($_builder, $_state, type, name, value, + mlir::StringAttr{}, constant, external); + }] + >]; let extraClassDeclaration = [{ cudaq::cc::PointerType getType() { auto globalTy = getGlobalType(); return cudaq::cc::PointerType::get(globalTy); } + + //===------------------------------------------------------------------===// + // SymbolOpInterface Methods + //===------------------------------------------------------------------===// + + bool isDeclaration() { return getExternal(); } }]; } diff --git a/lib/Frontend/nvqpp/ConvertExpr.cpp b/lib/Frontend/nvqpp/ConvertExpr.cpp index e6350d1c5c..fce215bc6f 100644 --- a/lib/Frontend/nvqpp/ConvertExpr.cpp +++ b/lib/Frontend/nvqpp/ConvertExpr.cpp @@ -2498,8 +2498,10 @@ bool QuakeBridgeVisitor::VisitInitListExpr(clang::InitListExpr *x) { { OpBuilder::InsertionGuard guard(builder); builder.setInsertionPointToEnd(module.getBody()); - builder.create(loc, globalTy, name, f64Attr, - /*constant=*/true); + builder + .create(loc, globalTy, name, f64Attr, + /*constant=*/true, /*external=*/false) + .setPrivate(); } auto ptrTy = cc::PointerType::get(globalTy); auto globalInit = builder.create(loc, ptrTy, name); diff --git a/lib/Optimizer/Builder/Intrinsics.cpp b/lib/Optimizer/Builder/Intrinsics.cpp index 315743f057..1774475b1b 100644 --- a/lib/Optimizer/Builder/Intrinsics.cpp +++ b/lib/Optimizer/Builder/Intrinsics.cpp @@ -481,9 +481,12 @@ static cc::GlobalOp buildVectorOfConstantElements(Location loc, ModuleOp module, OpBuilder::InsertionGuard guard(builder); builder.setInsertionPointToEnd(module.getBody()); auto globalTy = cc::ArrayType::get(ctx, eleTy, arrayAttr.size()); - return builder.create(loc, globalTy, name, arrayAttr, - /*constant=*/true, - /*external=*/false); + auto global = + builder.create(loc, globalTy, name, arrayAttr, + /*constant=*/true, + /*external=*/false); + global.setPrivate(); + return global; } template diff --git a/lib/Optimizer/CodeGen/Pipelines.cpp b/lib/Optimizer/CodeGen/Pipelines.cpp index 9a46b0c5b0..a504529126 100644 --- a/lib/Optimizer/CodeGen/Pipelines.cpp +++ b/lib/Optimizer/CodeGen/Pipelines.cpp @@ -50,6 +50,16 @@ void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) { pm.addNestedPass(createLiftArrayAlloc()); pm.addPass(createGlobalizeArrayValues()); pm.addPass(createStatePreparation()); + pm.addNestedPass(createGetConcreteMatrix()); + pm.addPass(createUnitarySynthesis()); + addAggressiveEarlyInlining(pm); + pm.addPass(createSymbolDCEPass()); + pm.addPass(createCanonicalizerPass()); + pm.addPass(createCSEPass()); + pm.addNestedPass(createMultiControlDecompositionPass()); + pm.addPass(createDecompositionPass( + {.enabledPatterns = {"CCZToCX", "RxAdjToRx", "RyAdjToRy", "RzAdjToRz"}})); + pm.addPass(createCanonicalizerPass()); } void cudaq::opt::addPipelineTranslateToIQMJson(PassManager &pm) { diff --git a/lib/Optimizer/Dialect/CC/CCOps.cpp b/lib/Optimizer/Dialect/CC/CCOps.cpp index 7708a42c36..67a7c57ccf 100644 --- a/lib/Optimizer/Dialect/CC/CCOps.cpp +++ b/lib/Optimizer/Dialect/CC/CCOps.cpp @@ -987,65 +987,6 @@ void cudaq::cc::ExtractValueOp::getCanonicalizationPatterns( patterns.add(context); } -//===----------------------------------------------------------------------===// -// GlobalOp -//===----------------------------------------------------------------------===// - -ParseResult cudaq::cc::GlobalOp::parse(OpAsmParser &parser, - OperationState &result) { - // Check for the `extern` optional keyword first. - if (succeeded(parser.parseOptionalKeyword("extern"))) - result.addAttribute(getExternalAttrName(result.name), - parser.getBuilder().getUnitAttr()); - - // Check for the `constant` optional keyword second. - if (succeeded(parser.parseOptionalKeyword("constant"))) - result.addAttribute(getConstantAttrName(result.name), - parser.getBuilder().getUnitAttr()); - - // Parse the rest of the global. - // @ ( ) : - StringAttr name; - if (parser.parseSymbolName(name, getSymNameAttrName(result.name), - result.attributes)) - return failure(); - if (succeeded(parser.parseOptionalLParen())) { - Attribute value; - if (parser.parseAttribute(value, getValueAttrName(result.name), - result.attributes) || - parser.parseRParen()) - return failure(); - } - SmallVector types; - if (parser.parseOptionalColonTypeList(types) || - parser.parseOptionalAttrDict(result.attributes)) - return failure(); - if (types.size() > 1) - return parser.emitError(parser.getNameLoc(), "expected zero or one type"); - result.addAttribute(getGlobalTypeAttrName(result.name), - TypeAttr::get(types[0])); - return success(); -} - -void cudaq::cc::GlobalOp::print(OpAsmPrinter &p) { - p << ' '; - if (getExternal()) - p << "extern "; - if (getConstant()) - p << "constant "; - p.printSymbolName(getSymName()); - if (auto value = getValue()) { - p << " ("; - p.printAttribute(*value); - p << ")"; - } - p << " : " << getGlobalType(); - p.printOptionalAttrDictWithKeyword( - (*this)->getAttrs(), - {getSymNameAttrName(), getValueAttrName(), getGlobalTypeAttrName(), - getConstantAttrName(), getExternalAttrName()}); -} - //===----------------------------------------------------------------------===// // StdvecDataOp //===----------------------------------------------------------------------===// diff --git a/lib/Optimizer/Transforms/DecompositionPatterns.cpp b/lib/Optimizer/Transforms/DecompositionPatterns.cpp index 54ee23741f..de32b86e45 100644 --- a/lib/Optimizer/Transforms/DecompositionPatterns.cpp +++ b/lib/Optimizer/Transforms/DecompositionPatterns.cpp @@ -1181,6 +1181,41 @@ struct RxToPhasedRx : public OpRewritePattern { } }; +// quake.rx (θ) target +// ───────────────────────────────── +// quake.rx(-θ) target +struct RxAdjToRx : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + void initialize() { setDebugName("RxAdjToRx"); } + + LogicalResult matchAndRewrite(quake::RxOp op, + PatternRewriter &rewriter) const override { + if (!op.getControls().empty()) + return failure(); + + if (!op.isAdj()) + return failure(); + + // Op info + Location loc = op->getLoc(); + Value target = op.getTarget(); + Value angle = op.getParameter(); + angle = rewriter.create(loc, angle); + + // Necessary/Helpful constants + SmallVector noControls; + SmallVector parameters = {angle}; + + QuakeOperatorCreator qRewriter(rewriter); + qRewriter.create(loc, parameters, noControls, target); + + qRewriter.selectWiresAndReplaceUses(op, target); + rewriter.eraseOp(op); + return success(); + } +}; + //===----------------------------------------------------------------------===// // RyOp decompositions //===----------------------------------------------------------------------===// @@ -1267,6 +1302,41 @@ struct RyToPhasedRx : public OpRewritePattern { } }; +// quake.ry (θ) target +// ───────────────────────────────── +// quake.ry(-θ) target +struct RyAdjToRy : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + void initialize() { setDebugName("RyAdjToRy"); } + + LogicalResult matchAndRewrite(quake::RyOp op, + PatternRewriter &rewriter) const override { + if (!op.getControls().empty()) + return failure(); + + if (!op.isAdj()) + return failure(); + + // Op info + Location loc = op->getLoc(); + Value target = op.getTarget(); + Value angle = op.getParameter(); + angle = rewriter.create(loc, angle); + + // Necessary/Helpful constants + SmallVector noControls; + SmallVector parameters = {angle}; + + QuakeOperatorCreator qRewriter(rewriter); + qRewriter.create(loc, parameters, noControls, target); + + qRewriter.selectWiresAndReplaceUses(op, target); + rewriter.eraseOp(op); + return success(); + } +}; + //===----------------------------------------------------------------------===// // RzOp decompositions //===----------------------------------------------------------------------===// @@ -1364,6 +1434,41 @@ struct RzToPhasedRx : public OpRewritePattern { } }; +// quake.rz (θ) target +// ───────────────────────────────── +// quake.rz(-θ) target +struct RzAdjToRz : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + void initialize() { setDebugName("RzAdjToRz"); } + + LogicalResult matchAndRewrite(quake::RzOp op, + PatternRewriter &rewriter) const override { + if (!op.getControls().empty()) + return failure(); + + if (!op.isAdj()) + return failure(); + + // Op info + Location loc = op->getLoc(); + Value target = op.getTarget(); + Value angle = op.getParameter(); + angle = rewriter.create(loc, angle); + + // Necessary/Helpful constants + SmallVector noControls; + SmallVector parameters = {angle}; + + QuakeOperatorCreator qRewriter(rewriter); + qRewriter.create(loc, parameters, noControls, target); + + qRewriter.selectWiresAndReplaceUses(op, target); + rewriter.eraseOp(op); + return success(); + } +}; + //===----------------------------------------------------------------------===// // U3Op decompositions //===----------------------------------------------------------------------===// @@ -1449,12 +1554,15 @@ void cudaq::populateWithAllDecompositionPatterns(RewritePatternSet &patterns) { // RxOp patterns CRxToCX, RxToPhasedRx, + RxAdjToRx, // RyOp patterns CRyToCX, RyToPhasedRx, + RyAdjToRy, // RzOp patterns CRzToCX, RzToPhasedRx, + RzAdjToRz, // Swap SwapToCX, // U3Op diff --git a/lib/Optimizer/Transforms/GetConcreteMatrix.cpp b/lib/Optimizer/Transforms/GetConcreteMatrix.cpp index 949da0f44c..2948b63649 100644 --- a/lib/Optimizer/Transforms/GetConcreteMatrix.cpp +++ b/lib/Optimizer/Transforms/GetConcreteMatrix.cpp @@ -47,6 +47,8 @@ class CustomUnitaryPattern if (!funcOp) return failure(); + funcOp.setPrivate(); + // The generator function returns a concrete matrix. If prior passes have // run to constant fold and lift array values, the generator function will // have address of the global variable which holds the concrete matrix. diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 42c7e82c13..0ca82c4736 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off diff --git a/targettests/braket/custom_operation_adj.cpp b/targettests/braket/custom_operation_adj.cpp new file mode 120000 index 0000000000..fd31ccab34 --- /dev/null +++ b/targettests/braket/custom_operation_adj.cpp @@ -0,0 +1 @@ +../execution/custom_operation_adj.cpp \ No newline at end of file diff --git a/targettests/braket/custom_operation_basic.cpp b/targettests/braket/custom_operation_basic.cpp new file mode 120000 index 0000000000..17b469fc6f --- /dev/null +++ b/targettests/braket/custom_operation_basic.cpp @@ -0,0 +1 @@ +../execution/custom_operation_basic.cpp \ No newline at end of file diff --git a/targettests/braket/graph_coloring-1.cpp b/targettests/braket/graph_coloring-1.cpp new file mode 120000 index 0000000000..101c19fe2b --- /dev/null +++ b/targettests/braket/graph_coloring-1.cpp @@ -0,0 +1 @@ +../execution/graph_coloring-1.cpp \ No newline at end of file diff --git a/targettests/braket/graph_coloring.cpp b/targettests/braket/graph_coloring.cpp new file mode 120000 index 0000000000..c9e81401b7 --- /dev/null +++ b/targettests/braket/graph_coloring.cpp @@ -0,0 +1 @@ +../execution/graph_coloring.cpp \ No newline at end of file diff --git a/targettests/braket/sudoku_2x2-1.cpp b/targettests/braket/sudoku_2x2-1.cpp deleted file mode 100644 index 30483fcd9b..0000000000 --- a/targettests/braket/sudoku_2x2-1.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * - * All rights reserved. * - * * - * This source code and the accompanying materials are made available under * - * the terms of the Apache License 2.0 which accompanies this distribution. * - ******************************************************************************/ - -// REQUIRES: c++20 -// clang-format off -// RUN: nvq++ --target anyon --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target braket --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target ionq --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target iqm --iqm-machine Apollo --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target oqc --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target quantinuum --emulate %s -o %t && %t | FileCheck %s -// XFAIL: * -// clang-format on - -#include -#include -#include -#include - -__qpu__ void reflect_uniform(cudaq::qvector<> &qubits) { - h(qubits); - x(qubits); - z(qubits[0], qubits[1], qubits[2], qubits[3]); - x(qubits); - h(qubits); -} - -__qpu__ void oracle(cudaq::qvector<> &cs, cudaq::qubit &target) { - x(cs[0], !cs[1], !cs[2], cs[3], target); - x(!cs[0], cs[1], cs[2], !cs[3], target); -} - -__qpu__ void grover() { - cudaq::qvector qubits(4); - cudaq::qubit ancilla; - - // Initialization - x(ancilla); - h(ancilla); - h(qubits); // uniform initialization - - // Don't work?: - for (int i = 0; i < 2; ++i) { - oracle(qubits, ancilla); - reflect_uniform(qubits); - } - - mz(qubits); -}; - -int main() { - auto result = cudaq::sample(1000, grover); - -#ifndef SYNTAX_CHECK - std::vector strings; - for (auto &&[bits, count] : result) { - strings.push_back(bits); - } - std::sort(strings.begin(), strings.end(), [&](auto &a, auto &b) { - return result.count(a) > result.count(b); - }); - std::cout << strings[0] << '\n'; - std::cout << strings[1] << '\n'; - - std::unordered_set most_probable{strings[0], strings[1]}; - assert(most_probable.count("1001") == 1); - assert(most_probable.count("0110") == 1); -#endif - - return 0; -} - -// CHECK-DAG: 1001 -// CHECK-DAG: 0110 diff --git a/targettests/braket/sudoku_2x2-1.cpp b/targettests/braket/sudoku_2x2-1.cpp new file mode 120000 index 0000000000..09aa81848d --- /dev/null +++ b/targettests/braket/sudoku_2x2-1.cpp @@ -0,0 +1 @@ +../execution/sudoku_2x2-1.cpp \ No newline at end of file diff --git a/targettests/braket/sudoku_2x2-bit_names.cpp b/targettests/braket/sudoku_2x2-bit_names.cpp deleted file mode 100644 index fe8f3b457a..0000000000 --- a/targettests/braket/sudoku_2x2-bit_names.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * - * All rights reserved. * - * * - * This source code and the accompanying materials are made available under * - * the terms of the Apache License 2.0 which accompanies this distribution. * - ******************************************************************************/ - -// REQUIRES: c++20 -// clang-format off -// RUN: nvq++ --target anyon --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target braket --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target ionq --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target iqm --iqm-machine Apollo --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target oqc --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target quantinuum --emulate %s -o %t && %t | FileCheck %s -// XFAIL: * -// clang-format on - -#include -#include -#include -#include - -__qpu__ void reflect_uniform(cudaq::qvector<> &qubits) { - h(qubits); - x(qubits); - z(qubits[0], qubits[1], qubits[2], qubits[3]); - x(qubits); - h(qubits); -} - -__qpu__ void oracle(cudaq::qvector<> &cs, cudaq::qubit &target) { - x(cs[0], !cs[1], !cs[2], cs[3], target); - x(!cs[0], cs[1], cs[2], !cs[3], target); -} - -__qpu__ void grover() { - cudaq::qvector qubits(4); - cudaq::qubit ancilla; - - // Initialization - x(ancilla); - h(ancilla); - h(qubits); // uniform initialization - - oracle(qubits, ancilla); - reflect_uniform(qubits); - oracle(qubits, ancilla); - reflect_uniform(qubits); - - auto groverQubits0 = mz(qubits[0]); - auto groverQubits1 = mz(qubits[1]); - auto groverQubits2 = mz(qubits[2]); - auto groverQubits3 = mz(qubits[3]); -}; - -int main() { - auto result = cudaq::sample(1000, grover); - result.dump(); - - auto& platform = cudaq::get_platform(); - if (platform.is_remote() || platform.is_emulated()) { - // Make sure that the get_marginal() results for the individual register names - // match the subset of the bits from the global register. - // Note that this will fail if you only compile this in library mode. - auto numBits = result.begin()->first.size(); - std::cout << "Checking " << numBits << " bits against global register\n"; - for (size_t b = 0; b < numBits; b++) { - auto regName = "groverQubits" + std::to_string(b); - auto valFromRegName = result.get_marginal({0}, regName); - auto valFromGlobal = result.get_marginal({b}); - if (valFromRegName.to_map() != valFromGlobal.to_map()) { - std::cout << "--- MISMATCH DETECTED in bit " << b << " ---\n"; - valFromRegName.dump(); - valFromGlobal.dump(); - // Mark test failure - assert(valFromRegName.to_map() == valFromGlobal.to_map()); - } - } - } - -#ifndef SYNTAX_CHECK - std::vector strings; - for (auto &&[bits, count] : result) { - strings.push_back(bits); - } - std::sort(strings.begin(), strings.end(), [&](auto& a, auto& b) { - return result.count(a) > result.count(b); - }); - std::cout << strings[0] << '\n'; - std::cout << strings[1] << '\n'; - - std::unordered_set most_probable{strings[0], strings[1]}; - assert(most_probable.count("1001") == 1); - assert(most_probable.count("0110") == 1); -#endif - - return 0; -} - -// CHECK-DAG: 1001 -// CHECK-DAG: 0110 diff --git a/targettests/braket/sudoku_2x2-bit_names.cpp b/targettests/braket/sudoku_2x2-bit_names.cpp new file mode 120000 index 0000000000..15e2b47ae2 --- /dev/null +++ b/targettests/braket/sudoku_2x2-bit_names.cpp @@ -0,0 +1 @@ +../execution/sudoku_2x2-bit_names.cpp \ No newline at end of file diff --git a/targettests/braket/sudoku_2x2-reg_name.cpp b/targettests/braket/sudoku_2x2-reg_name.cpp deleted file mode 100644 index a8adc0e8cc..0000000000 --- a/targettests/braket/sudoku_2x2-reg_name.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * - * All rights reserved. * - * * - * This source code and the accompanying materials are made available under * - * the terms of the Apache License 2.0 which accompanies this distribution. * - ******************************************************************************/ - -// REQUIRES: c++20 -// clang-format off -// RUN: nvq++ --target anyon --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target braket --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target ionq --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target iqm --iqm-machine Apollo --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target oqc --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target quantinuum --emulate %s -o %t && %t | FileCheck %s -// XFAIL: * -// clang-format on - -#include -#include -#include -#include - -__qpu__ void reflect_uniform(cudaq::qvector<> &qubits) { - h(qubits); - x(qubits); - z(qubits[0], qubits[1], qubits[2], qubits[3]); - x(qubits); - h(qubits); -} - -__qpu__ void oracle(cudaq::qvector<> &cs, cudaq::qubit &target) { - x(cs[0], !cs[1], !cs[2], cs[3], target); - x(!cs[0], cs[1], cs[2], !cs[3], target); -} - -__qpu__ void grover() { - cudaq::qvector qubits(4); - cudaq::qubit ancilla; - - // Initialization - x(ancilla); - h(ancilla); - h(qubits); // uniform initialization - - oracle(qubits, ancilla); - reflect_uniform(qubits); - oracle(qubits, ancilla); - reflect_uniform(qubits); - - auto groverQubits = mz(qubits); -}; - -int main() { - auto result = cudaq::sample(1000, grover); - result.dump(); - -#ifndef SYNTAX_CHECK - std::vector strings; - for (auto &&[bits, count] : result) { - strings.push_back(bits); - } - std::sort(strings.begin(), strings.end(), [&](auto& a, auto& b) { - return result.count(a) > result.count(b); - }); - std::cout << strings[0] << '\n'; - std::cout << strings[1] << '\n'; - - std::unordered_set most_probable{strings[0], strings[1]}; - assert(most_probable.count("1001") == 1); - assert(most_probable.count("0110") == 1); -#endif - - return 0; -} - -// CHECK-DAG: 1001 -// CHECK-DAG: 0110 diff --git a/targettests/braket/sudoku_2x2-reg_name.cpp b/targettests/braket/sudoku_2x2-reg_name.cpp new file mode 120000 index 0000000000..367a2098f4 --- /dev/null +++ b/targettests/braket/sudoku_2x2-reg_name.cpp @@ -0,0 +1 @@ +../execution/sudoku_2x2-reg_name.cpp \ No newline at end of file diff --git a/targettests/braket/sudoku_2x2.cpp b/targettests/braket/sudoku_2x2.cpp deleted file mode 100644 index eb63d51e33..0000000000 --- a/targettests/braket/sudoku_2x2.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * - * All rights reserved. * - * * - * This source code and the accompanying materials are made available under * - * the terms of the Apache License 2.0 which accompanies this distribution. * - ******************************************************************************/ - -// REQUIRES: c++20 -// clang-format off -// RUN: nvq++ --target anyon --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target braket --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target ionq --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target iqm --iqm-machine Apollo --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target oqc --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target quantinuum --emulate %s -o %t && %t | FileCheck %s -// XFAIL: * -// clang-format on - -#include -#include -#include -#include - -__qpu__ void reflect_uniform(cudaq::qvector<> &qubits) { - h(qubits); - x(qubits); - z(qubits[0], qubits[1], qubits[2], qubits[3]); - x(qubits); - h(qubits); -} - -__qpu__ void oracle(cudaq::qvector<> &cs, cudaq::qubit &target) { - x(cs[0], !cs[1], !cs[2], cs[3], target); - x(!cs[0], cs[1], cs[2], !cs[3], target); -} - -__qpu__ void grover() { - cudaq::qvector qubits(4); - cudaq::qubit ancilla; - - // Initialization - x(ancilla); - h(ancilla); - h(qubits); // uniform initialization - - oracle(qubits, ancilla); - reflect_uniform(qubits); - oracle(qubits, ancilla); - reflect_uniform(qubits); - - mz(qubits); -}; - -int main() { - auto result = cudaq::sample(1000, grover); - -#ifndef SYNTAX_CHECK - std::vector strings; - for (auto &&[bits, count] : result) { - strings.push_back(bits); - } - std::sort(strings.begin(), strings.end(), [&](auto& a, auto& b) { - return result.count(a) > result.count(b); - }); - std::cout << strings[0] << '\n'; - std::cout << strings[1] << '\n'; - - std::unordered_set most_probable{strings[0], strings[1]}; - assert(most_probable.count("1001") == 1); - assert(most_probable.count("0110") == 1); -#endif - - return 0; -} - -// CHECK-DAG: 1001 -// CHECK-DAG: 0110 diff --git a/targettests/braket/sudoku_2x2.cpp b/targettests/braket/sudoku_2x2.cpp new file mode 120000 index 0000000000..23748412f1 --- /dev/null +++ b/targettests/braket/sudoku_2x2.cpp @@ -0,0 +1 @@ +../execution/sudoku_2x2.cpp \ No newline at end of file diff --git a/targettests/execution/custom_operation_adj.cpp b/targettests/execution/custom_operation_adj.cpp index 547942b08f..9541dd492a 100644 --- a/targettests/execution/custom_operation_adj.cpp +++ b/targettests/execution/custom_operation_adj.cpp @@ -6,12 +6,15 @@ * the terms of the Apache License 2.0 which accompanies this distribution. * ******************************************************************************/ -// RUN: nvq++ %cpp_std --enable-mlir %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target anyon --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target ionq --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target iqm --emulate --iqm-machine Apollo %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target oqc --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target quantinuum --emulate %s -o %t && %t | FileCheck %s +// clang-format off +// RUN: nvq++ -std=c++17 --enable-mlir %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target anyon --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target braket --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target ionq --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target iqm --iqm-machine Apollo --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target oqc --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target quantinuum --emulate %s -o %t && %t | FileCheck %s +// clang-format on #include diff --git a/targettests/execution/custom_operation_basic.cpp b/targettests/execution/custom_operation_basic.cpp index 77c8020a3e..9c5724c390 100644 --- a/targettests/execution/custom_operation_basic.cpp +++ b/targettests/execution/custom_operation_basic.cpp @@ -6,12 +6,15 @@ * the terms of the Apache License 2.0 which accompanies this distribution. * ******************************************************************************/ -// RUN: nvq++ %cpp_std --enable-mlir %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target anyon --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target ionq --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target iqm --emulate --iqm-machine Apollo %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target oqc --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target quantinuum --emulate %s -o %t && %t | FileCheck %s +// clang-format off +// RUN: nvq++ -std=c++17 --enable-mlir %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target anyon --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target braket --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target ionq --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target iqm --iqm-machine Apollo --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target oqc --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target quantinuum --emulate %s -o %t && %t | FileCheck %s +// clang-format on #include diff --git a/targettests/execution/graph_coloring-1.cpp b/targettests/execution/graph_coloring-1.cpp index 4ac3eaa33a..794e607f14 100644 --- a/targettests/execution/graph_coloring-1.cpp +++ b/targettests/execution/graph_coloring-1.cpp @@ -8,7 +8,8 @@ // REQUIRES: c++20 // clang-format off -// RUN: nvq++ %s -o %t --target quantinuum --emulate && %t | FileCheck %s +// RUN: nvq++ --target braket --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ --target quantinuum --emulate %s -o %t && %t | FileCheck %s // clang-format on #include diff --git a/targettests/execution/graph_coloring.cpp b/targettests/execution/graph_coloring.cpp index 1cce92096c..e3ab5c5f40 100644 --- a/targettests/execution/graph_coloring.cpp +++ b/targettests/execution/graph_coloring.cpp @@ -8,7 +8,8 @@ // REQUIRES: c++20 // clang-format off -// RUN: nvq++ %s -o %t --target quantinuum --emulate && %t | FileCheck %s +// RUN: nvq++ --target braket --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ --target quantinuum --emulate %s -o %t && %t | FileCheck %s // clang-format on #include diff --git a/test/Transforms/DecompositionPatterns/RxAdjToRx.qke b/test/Transforms/DecompositionPatterns/RxAdjToRx.qke new file mode 100644 index 0000000000..b8bfd2ab32 --- /dev/null +++ b/test/Transforms/DecompositionPatterns/RxAdjToRx.qke @@ -0,0 +1,25 @@ +// ========================================================================== // +// Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. // +// All rights reserved. // +// // +// This source code and the accompanying materials are made available under // +// the terms of the Apache License 2.0 which accompanies this distribution. // +// ========================================================================== // + +// RUN: cudaq-opt -pass-pipeline='builtin.module(decomposition{enable-patterns=RxAdjToRx})' %s | FileCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(decomposition{enable-patterns=RxAdjToRx})' %s | CircuitCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(func.func(expand-control-veqs,memtoreg),decomposition{enable-patterns=RxAdjToRx})' %s | FileCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(func.func(expand-control-veqs,memtoreg),decomposition{enable-patterns=RxAdjToRx})' %s | CircuitCheck %s + +// Test the decomposition pattern with different control types. The FileCheck +// part of this test only cares about the sequence of operations. Correcteness +// is checked by CircuitCheck. + +// CHECK-LABEL: func.func @qref_no_control +func.func @qref_no_control(%t: !quake.ref) { + %0 = arith.constant 1.57079632679489660 : f64 + // CHECK: quake.rx + quake.rx (%0) %t : (f64, !quake.ref) -> () + return +} + diff --git a/test/Transforms/DecompositionPatterns/RyAdjToRy.qke b/test/Transforms/DecompositionPatterns/RyAdjToRy.qke new file mode 100644 index 0000000000..a6cc71fbac --- /dev/null +++ b/test/Transforms/DecompositionPatterns/RyAdjToRy.qke @@ -0,0 +1,25 @@ +// ========================================================================== // +// Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. // +// All rights reserved. // +// // +// This source code and the accompanying materials are made available under // +// the terms of the Apache License 2.0 which accompanies this distribution. // +// ========================================================================== // + +// RUN: cudaq-opt -pass-pipeline='builtin.module(decomposition{enable-patterns=RyAdjToRy})' %s | FileCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(decomposition{enable-patterns=RyAdjToRy})' %s | CircuitCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(func.func(expand-control-veqs,memtoreg),decomposition{enable-patterns=RyAdjToRy})' %s | FileCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(func.func(expand-control-veqs,memtoreg),decomposition{enable-patterns=RyAdjToRy})' %s | CircuitCheck %s + +// Test the decomposition pattern with different control types. The FileCheck +// part of this test only cares about the sequence of operations. Correcteness +// is checked by CircuitCheck. + +// CHECK-LABEL: func.func @qref_no_control +func.func @qref_no_control(%t: !quake.ref) { + %0 = arith.constant 1.57079632679489660 : f64 + // CHECK: quake.ry + quake.ry (%0) %t : (f64, !quake.ref) -> () + return +} + diff --git a/test/Transforms/DecompositionPatterns/RzAdjToRz.qke b/test/Transforms/DecompositionPatterns/RzAdjToRz.qke new file mode 100644 index 0000000000..81adb3f499 --- /dev/null +++ b/test/Transforms/DecompositionPatterns/RzAdjToRz.qke @@ -0,0 +1,25 @@ +// ========================================================================== // +// Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. // +// All rights reserved. // +// // +// This source code and the accompanying materials are made available under // +// the terms of the Apache License 2.0 which accompanies this distribution. // +// ========================================================================== // + +// RUN: cudaq-opt -pass-pipeline='builtin.module(decomposition{enable-patterns=RzAdjToRz})' %s | FileCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(decomposition{enable-patterns=RzAdjToRz})' %s | CircuitCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(func.func(expand-control-veqs,memtoreg),decomposition{enable-patterns=RzAdjToRz})' %s | FileCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(func.func(expand-control-veqs,memtoreg),decomposition{enable-patterns=RzAdjToRz})' %s | CircuitCheck %s + +// Test the decomposition pattern with different control types. The FileCheck +// part of this test only cares about the sequence of operations. Correcteness +// is checked by CircuitCheck. + +// CHECK-LABEL: func.func @qref_no_control +func.func @qref_no_control(%t: !quake.ref) { + %0 = arith.constant 1.57079632679489660 : f64 + // CHECK: quake.rz + quake.rz (%0) %t : (f64, !quake.ref) -> () + return +} + diff --git a/test/Translate/translate_openqasm2_adj_rotations.cpp b/test/Translate/translate_openqasm2_adj_rotations.cpp new file mode 100644 index 0000000000..b9cbb2bac6 --- /dev/null +++ b/test/Translate/translate_openqasm2_adj_rotations.cpp @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * + * All rights reserved. * + * * + * This source code and the accompanying materials are made available under * + * the terms of the Apache License 2.0 which accompanies this distribution. * + ******************************************************************************/ + +// RUN: cudaq-quake %s | cudaq-translate --convert-to=openqasm2 | FileCheck %s + +#include +#include +#include + +struct kernel { + void operator()() __qpu__ { + double theta = 0.67; + cudaq::qvector qubits(6); + + x(qubits[5]); + h(qubits[4], qubits[5]); + rx(theta, qubits[4]); + + x(qubits[3]); + h(qubits[2], qubits[3]); + ry(theta, qubits[2]); + + x(qubits[1]); + h(qubits[0], qubits[1]); + rz(theta, qubits[0]); + + mz(qubits); + } +}; + + +int main() { + auto counts = cudaq::sample(kernel{}); + counts.dump(); +} + +// CHECK: // Code generated by NVIDIA's nvq++ compiler +// CHECK: OPENQASM 2.0; + +// CHECK: include "qelib1.inc"; + +// CHECK: gate ZN6kernelclEv(param0) { +// CHECK: } + +// CHECK: qreg var0[6]; +// CHECK: x var0[5]; +// CHECK: ch var0[4], var0[5]; +// CHECK: rx(-6.700000e-01) var0[4]; +// CHECK: x var0[3]; +// CHECK: ch var0[2], var0[3]; +// CHECK: ry(-6.700000e-01) var0[2]; +// CHECK: x var0[1]; +// CHECK: ch var0[0], var0[1]; +// CHECK: rz(-6.700000e-01) var0[0]; +// CHECK: creg var7[6]; +// CHECK: measure var0 -> var7; diff --git a/test/Translate/translate_openqasm2_custom_operation.cpp b/test/Translate/translate_openqasm2_custom_operation.cpp new file mode 100644 index 0000000000..dd1a397ad1 --- /dev/null +++ b/test/Translate/translate_openqasm2_custom_operation.cpp @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * + * All rights reserved. * + * * + * This source code and the accompanying materials are made available under * + * the terms of the Apache License 2.0 which accompanies this distribution. * + ******************************************************************************/ + +// RUN: cudaq-quake %s | cudaq-translate --convert-to=openqasm2 | FileCheck %s + +#include + +CUDAQ_REGISTER_OPERATION(custom_h, 1, 0, + {M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2}) + +CUDAQ_REGISTER_OPERATION(custom_cnot, 2, 0, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0}) + +__qpu__ void bell_pair() { + cudaq::qubit q, r; + custom_h(q); + custom_cnot(q, r); +} + +// CHECK: // Code generated by NVIDIA's nvq++ compiler +// CHECK: OPENQASM 2.0; + +// CHECK: include "qelib1.inc"; + +// CHECK: gate Z9bell_pairv { +// CHECK: } + +// CHECK: qreg var0[1]; +// CHECK: qreg var1[1]; +// CHECK: rz(3.141593e+00) var0[0]; +// CHECK: ry(1.570796e+00) var0[0]; +// CHECK: u1(3.141593e+00) var0[0]; +// CHECK: rz(-3.141593e+00) var0[0]; +// CHECK: ry(1.570796e+00) var1[0]; +// CHECK: rz(2.725460e+00) var1[0]; +// CHECK: rz(-3.406437e+00) var0[0]; +// CHECK: rz(3.999978e-01) var0[0]; +// CHECK: rx(1.570796e+00) var0[0]; +// CHECK: rx(1.570796e+00) var1[0]; +// CHECK: cx var1[0], var0[0]; +// CHECK: rz(-3.141593e+00) var0[0]; +// CHECK: cx var1[0], var0[0]; +// CHECK: rx(-1.570796e+00) var1[0]; +// CHECK: rx(-1.570796e+00) var0[0]; +// CHECK: cx var1[0], var0[0]; +// CHECK: rz(-1.570796e+00) var0[0]; +// CHECK: cx var1[0], var0[0]; +// CHECK: rz(1.154664e+00) var1[0]; +// CHECK: ry(1.570796e+00) var1[0]; +// CHECK: rz(1.893954e+00) var0[0]; +// CHECK: ry(3.141593e+00) var0[0]; +// CHECK: rz(3.329597e+00) var0[0]; +// CHECK: u1(1.570796e+00) var0[0]; +// CHECK: rz(-1.570796e+00) var0[0]; \ No newline at end of file From 6744327d8071134682648e6eb71b4735be040af4 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 15 Nov 2024 11:44:59 -0800 Subject: [PATCH 02/47] Fix failing tests Signed-off-by: Anna Gringauze --- include/cudaq/Optimizer/Dialect/CC/CCOps.td | 2 +- include/cudaq/Optimizer/Transforms/Passes.td | 4 ++-- lib/Optimizer/CodeGen/Pipelines.cpp | 1 - lib/Optimizer/Transforms/StatePreparation.cpp | 1 + python/tests/mlir/custom_op_builder.py | 6 +++--- python/tests/mlir/custom_operation.py | 8 ++++---- runtime/test/test_argument_conversion.cpp | 4 ++-- test/AST-Quake/custom_op_concrete_matrix.cpp | 4 ++-- test/AST-Quake/initialization_list.cpp | 2 +- test/Quake-QIR/custom_operation.qke | 4 ++-- test/Quake/add_dealloc-1.qke | 4 ++-- test/Quake/delete_states.qke | 8 ++++---- test/Quake/lift_array.qke | 6 +++--- test/Quake/state_prep.qke | 8 ++++---- test/Transforms/UnitarySynthesis/adjoint_test.qke | 4 ++-- test/Transforms/UnitarySynthesis/basic_test.qke | 2 +- test/Transforms/UnitarySynthesis/bell_pair.qke | 4 ++-- test/Transforms/UnitarySynthesis/random_unitary_1.qke | 2 +- test/Transforms/UnitarySynthesis/random_unitary_2.qke | 2 +- test/Transforms/UnitarySynthesis/random_unitary_3.qke | 2 +- test/Transforms/UnitarySynthesis/random_unitary_4.qke | 2 +- test/Transforms/UnitarySynthesis/random_unitary_5.qke | 2 +- test/Translate/translate_openqasm2_loop.cpp | 4 ++-- 23 files changed, 43 insertions(+), 43 deletions(-) diff --git a/include/cudaq/Optimizer/Dialect/CC/CCOps.td b/include/cudaq/Optimizer/Dialect/CC/CCOps.td index 71e1702a97..31baeb640e 100644 --- a/include/cudaq/Optimizer/Dialect/CC/CCOps.td +++ b/include/cudaq/Optimizer/Dialect/CC/CCOps.td @@ -912,7 +912,7 @@ def cc_GlobalOp : CCOp<"global", [IsolatedFromAbove, Symbol]> { let arguments = (ins TypeAttr:$global_type, - StrAttr:$sym_name, + SymbolNameAttr:$sym_name, OptionalAttr:$value, OptionalAttr:$sym_visibility, UnitAttr:$constant, diff --git a/include/cudaq/Optimizer/Transforms/Passes.td b/include/cudaq/Optimizer/Transforms/Passes.td index da6f3163b3..1c3640dd4c 100644 --- a/include/cudaq/Optimizer/Transforms/Passes.td +++ b/include/cudaq/Optimizer/Transforms/Passes.td @@ -407,7 +407,7 @@ def GetConcreteMatrix : Pass<"get-concrete-matrix", "mlir::func::FuncOp"> { return } - cc.global constant @__nvqpp__mlirgen__function_foo_generator_1.bar.rodata_0 ((dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp__mlirgen__function_foo_generator_1.bar.rodata_0 ((dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} } ``` @@ -816,7 +816,7 @@ def StatePreparation : Pass<"state-prep", "mlir::ModuleOp"> { %2 = quake.init_state %1, %0 : (!quake.veq<2>, !cc.ptr x 4>>) -> !quake.veq<2> return } - cc.global constant @foo.rodata_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @foo.rodata_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} } ``` Will be rewritten to: diff --git a/lib/Optimizer/CodeGen/Pipelines.cpp b/lib/Optimizer/CodeGen/Pipelines.cpp index a504529126..23e7c83f5f 100644 --- a/lib/Optimizer/CodeGen/Pipelines.cpp +++ b/lib/Optimizer/CodeGen/Pipelines.cpp @@ -52,7 +52,6 @@ void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) { pm.addPass(createStatePreparation()); pm.addNestedPass(createGetConcreteMatrix()); pm.addPass(createUnitarySynthesis()); - addAggressiveEarlyInlining(pm); pm.addPass(createSymbolDCEPass()); pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); diff --git a/lib/Optimizer/Transforms/StatePreparation.cpp b/lib/Optimizer/Transforms/StatePreparation.cpp index be4832c960..42685f5252 100644 --- a/lib/Optimizer/Transforms/StatePreparation.cpp +++ b/lib/Optimizer/Transforms/StatePreparation.cpp @@ -299,6 +299,7 @@ class StateDecomposer { /// cc.global constant @foo.rodata_0 (dense<[(0.707106769,0.000000e+00), /// (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), /// (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : +/// {sym_visibility = "private"} /// !cc.array x 4> /// } /// ``` diff --git a/python/tests/mlir/custom_op_builder.py b/python/tests/mlir/custom_op_builder.py index 3efc53d23a..67ad888e58 100644 --- a/python/tests/mlir/custom_op_builder.py +++ b/python/tests/mlir/custom_op_builder.py @@ -80,6 +80,6 @@ def register_custom_operations(matrix): # CHECK: quake.custom_op @__nvqpp__mlirgen__foo_2_generator_1.rodata {{\[}}%[[VAL_4]]] %[[VAL_3]] : (!quake.veq<2>, !quake.veq<1>) -> () # CHECK: return # CHECK: } -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_0_generator_1.rodata (dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_1_generator_1.rodata (dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_2_generator_1.rodata (dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_0_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_1_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_2_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} \ No newline at end of file diff --git a/python/tests/mlir/custom_operation.py b/python/tests/mlir/custom_operation.py index c31528e623..9fbb119822 100644 --- a/python/tests/mlir/custom_operation.py +++ b/python/tests/mlir/custom_operation.py @@ -35,8 +35,8 @@ def bell(): # CHECK: quake.custom_op @__nvqpp__mlirgen__custom_x_generator_1.rodata {{\[}}%[[VAL_1]]] %[[VAL_2]] : (!quake.ref, !quake.ref) -> () # CHECK: return # CHECK: } -# CHECK: cc.global constant @__nvqpp__mlirgen__custom_h_generator_1.rodata (dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> -# CHECK: cc.global constant @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__custom_h_generator_1.rodata(dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__custom_x_generator_1.rodata(dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} def test_custom_adjoint(): @@ -64,5 +64,5 @@ def kernel(): # CHECK: quake.h %[[VAL_0]] : (!quake.ref) -> () # CHECK: return # CHECK: } -# CHECK: cc.global constant @__nvqpp__mlirgen__custom_s_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> -# CHECK: cc.global constant @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__custom_s_generator_1.rodata(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} diff --git a/runtime/test/test_argument_conversion.cpp b/runtime/test/test_argument_conversion.cpp index 9fe3d92f8f..4719430537 100644 --- a/runtime/test/test_argument_conversion.cpp +++ b/runtime/test/test_argument_conversion.cpp @@ -388,7 +388,7 @@ void test_state(mlir::MLIRContext *ctx) { // CHECK: %[[VAL_5:.*]] = func.call @__nvqpp_cudaq_state_createFromData_fp64(%[[VAL_4]], %[[VAL_2]]) : (!cc.ptr, i64) -> !cc.ptr // CHECK: %[[VAL_6:.*]] = cc.cast %[[VAL_5]] : (!cc.ptr) -> !cc.ptr // CHECK: } -// CHECK-DAG: cc.global constant @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> +// CHECK-DAG: cc.global constant @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} // CHECK-DAG: func.func private @__nvqpp_cudaq_state_createFromData_fp64(!cc.ptr, i64) -> !cc.ptr // clang-format on } @@ -498,7 +498,7 @@ void test_combinations(mlir::MLIRContext *ctx) { // CHECK: %[[VAL_5:.*]] = func.call @__nvqpp_cudaq_state_createFromData_fp64(%[[VAL_4]], %[[VAL_2]]) : (!cc.ptr, i64) -> !cc.ptr // CHECK: %[[VAL_6:.*]] = cc.cast %[[VAL_5]] : (!cc.ptr) -> !cc.ptr // CHECK: } -// CHECK-DAG: cc.global constant @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> +// CHECK-DAG: cc.global constant @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} // CHECK-DAG: func.func private @__nvqpp_cudaq_state_createFromData_fp64(!cc.ptr, i64) -> !cc.ptr // CHECK-LABEL: cc.arg_subst[2] { // CHECK: %[[VAL_0:.*]] = cc.alloca !cc.array diff --git a/test/AST-Quake/custom_op_concrete_matrix.cpp b/test/AST-Quake/custom_op_concrete_matrix.cpp index 5ab0313fab..f0a849f28d 100644 --- a/test/AST-Quake/custom_op_concrete_matrix.cpp +++ b/test/AST-Quake/custom_op_concrete_matrix.cpp @@ -33,5 +33,5 @@ __qpu__ void kernel_1() { // CHECK: return // CHECK: } -// CHECK-DAG: cc.global constant @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}} (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> -// CHECK-DAG: cc.global constant @__nvqpp__mlirgen__function_custom_cnot_generator_2._Z23custom_cnot_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}} (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<16xcomplex>) : !cc.array x 16> +// CHECK-DAG: cc.global constant @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}}(dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +// CHECK-DAG: cc.global constant @__nvqpp__mlirgen__function_custom_cnot_generator_2._Z23custom_cnot_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}}(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<16xcomplex>) : !cc.array x 16> {sym_visibility = "private"} diff --git a/test/AST-Quake/initialization_list.cpp b/test/AST-Quake/initialization_list.cpp index 7e05b80562..8067ededd7 100644 --- a/test/AST-Quake/initialization_list.cpp +++ b/test/AST-Quake/initialization_list.cpp @@ -44,5 +44,5 @@ __qpu__ void g() { // CHECK: return // CHECK: } -// CHECK: cc.global constant @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00]> : tensor<4xf64>) : !cc.array +// CHECK: cc.global constant @__nvqpp__rodata_init_0(dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00]> : tensor<4xf64>) : !cc.array {sym_visibility = "private"} diff --git a/test/Quake-QIR/custom_operation.qke b/test/Quake-QIR/custom_operation.qke index 0aad978c78..0127901521 100644 --- a/test/Quake-QIR/custom_operation.qke +++ b/test/Quake-QIR/custom_operation.qke @@ -19,8 +19,8 @@ module { %measOut = quake.mz %0 : (!quake.ref) -> !quake.measure return } - cc.global constant @__nvqpp__mlirgen__function_custom_s_generator_1._Z20custom_s_generator_1RKSt6vectorIdSaIdEE.rodata_0 (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> - cc.global constant @__nvqpp__mlirgen__function_custom_s_adj_generator_1._Z24custom_s_adj_generator_1RKSt6vectorIdSaIdEE.rodata_1 (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp__mlirgen__function_custom_s_generator_1._Z20custom_s_generator_1RKSt6vectorIdSaIdEE.rodata_0 (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant @__nvqpp__mlirgen__function_custom_s_adj_generator_1._Z24custom_s_adj_generator_1RKSt6vectorIdSaIdEE.rodata_1 (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} } diff --git a/test/Quake/add_dealloc-1.qke b/test/Quake/add_dealloc-1.qke index 50fd22b52e..454f976fe3 100644 --- a/test/Quake/add_dealloc-1.qke +++ b/test/Quake/add_dealloc-1.qke @@ -31,7 +31,7 @@ module { } {invariant} return } - cc.global constant @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 0.000000e+00, 5.000000e-01, 5.000000e-01]> : tensor<4xf64>) : !cc.array + cc.global constant @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 0.000000e+00, 5.000000e-01, 5.000000e-01]> : tensor<4xf64>) : !cc.array {sym_visibility = "private"} } // CHECK-LABEL: func.func @__nvqpp__mlirgen__FromState() { @@ -41,5 +41,5 @@ module { // CHECK: quake.dealloc %[[VAL_5]] : !quake.veq<4> // CHECK: return // CHECK: } -// CHECK: cc.global constant @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 0.000000e+00, 5.000000e-01, 5.000000e-01]> : tensor<4xf64>) : !cc.array +// CHECK: cc.global constant @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 0.000000e+00, 5.000000e-01, 5.000000e-01]> : tensor<4xf64>) : !cc.array {sym_visibility = "private"} diff --git a/test/Quake/delete_states.qke b/test/Quake/delete_states.qke index caa7cca621..634161b1e0 100644 --- a/test/Quake/delete_states.qke +++ b/test/Quake/delete_states.qke @@ -24,7 +24,7 @@ module { } func.func private @__nvqpp_cudaq_state_numberOfQubits(!cc.ptr) -> i64 cc.global constant @function_test_state_param._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00 -,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> +,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} func.func private @__nvqpp_cudaq_state_createFromData_fp32(!cc.ptr, i64) -> !cc.ptr // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_state_param._Z16test_state_paramPN5cudaq5stateE() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { @@ -35,7 +35,7 @@ module { // CHECK: %[[VAL_3:.*]] = quake.alloca !quake.veq<3> // CHECK: %[[VAL_4:.*]] = quake.init_state %[[VAL_3]], %[[VAL_2]] : (!quake.veq<3>, !cc.ptr x 8>>) -> !quake.veq<3> // CHECK: } -// CHECK-DAG: cc.global constant @function_test_state_param._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> +// CHECK-DAG: cc.global constant @function_test_state_param._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} func.func @__nvqpp__mlirgen__sub_kernel(%arg : !cc.ptr) attributes {"cudaq-kernel", no_this} { %0 = call @__nvqpp_cudaq_state_numberOfQubits(%arg) : (!cc.ptr) -> i64 @@ -57,7 +57,7 @@ module { } cc.global constant @function_test_state_param1._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00 -,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> +,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} // CHECK: func.func @__nvqpp__mlirgen__sub_kernel(%[[VAL_ARG:.*]]: !cc.ptr) attributes {"cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = call @__nvqpp_cudaq_state_numberOfQubits(%[[VAL_ARG]]) : (!cc.ptr) -> i64 @@ -78,7 +78,7 @@ module { // CHECK: call @__nvqpp_cudaq_state_delete(%[[VAL_5]]) : (!cc.ptr) -> () // CHECK: return // CHECK: } -// CHECK-DAG: constant @function_test_state_param1._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> +// CHECK-DAG: cc.global constant @function_test_state_param1._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} // CHECK-DAG: func.func private @__nvqpp_cudaq_state_delete(!cc.ptr) } diff --git a/test/Quake/lift_array.qke b/test/Quake/lift_array.qke index b7cbcec5cd..1179aa6bd4 100644 --- a/test/Quake/lift_array.qke +++ b/test/Quake/lift_array.qke @@ -122,6 +122,6 @@ func.func @test2() -> !quake.veq<2> { // GLOBAL: return %[[VAL_2]] : !quake.veq<2> // GLOBAL: } -// GLOBAL-DAG: cc.global constant @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv.rodata_{{[0-9]+}} (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> -// GLOBAL-DAG: cc.global constant @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_1v.rodata_{{[0-9]+}} (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> -// GLOBAL-DAG: cc.global constant @test2.rodata_{{[0-9]+}} (dense<[1.000000e+00, 2.000000e+00, 6.000000e+00, 9.000000e+00]> : tensor<4xf64>) : !cc.array +// GLOBAL-DAG: cc.global constant @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv.rodata_{{[0-9]+}} (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +// GLOBAL-DAG: cc.global constant @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_1v.rodata_{{[0-9]+}} (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +// GLOBAL-DAG: cc.global constant @test2.rodata_{{[0-9]+}} (dense<[1.000000e+00, 2.000000e+00, 6.000000e+00, 9.000000e+00]>" : tensor<4xf64>) : !cc.array {sym_visibility = "private"} diff --git a/test/Quake/state_prep.qke b/test/Quake/state_prep.qke index 4289571b33..969f38ee44 100644 --- a/test/Quake/state_prep.qke +++ b/test/Quake/state_prep.qke @@ -15,7 +15,7 @@ module { %2 = quake.init_state %1, %0 : (!quake.veq<2>, !cc.ptr x 4>>) -> !quake.veq<2> return } - cc.global constant @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv.rodata_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv.rodata_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = arith.constant 0.78539816339744839 : f64 @@ -37,7 +37,7 @@ module { %2 = quake.init_state %1, %0 : (!quake.veq<2>, !cc.ptr>) -> !quake.veq<2> return } - cc.global constant @__nvqpp__mlirgen__function_test_real_constant_array._Z24test_real_constant_arrayv.rodata_0 (dense<[0.70710678118654757, 0.70710678118654757, 0.000000e+00, 0.000000e+00]> : tensor<4xf64>) : !cc.array + cc.global constant @__nvqpp__mlirgen__function_test_real_constant_array._Z24test_real_constant_arrayv.rodata_0 (dense<[0.70710678118654757, 0.70710678118654757, 0.000000e+00, 0.000000e+00]> : tensor<4xf64>) : !cc.array {sym_visibility = "private"} // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_real_constant_array._Z24test_real_constant_arrayv() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = arith.constant 0.78539816339744839 : f64 @@ -60,7 +60,7 @@ module { %3 = quake.init_state %2, %1 : (!quake.veq<2>, !cc.ptr x ?>>) -> !quake.veq<2> return } - cc.global constant @__nvqpp_rodata_init_state.0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp_rodata_init_state.0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_complex_array_param._Z24test_complex_array_paramSt6vectorISt7complexIfESaIS1_EE() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = arith.constant 0.78539816339744839 : f64 @@ -83,7 +83,7 @@ module { %3 = quake.init_state %2, %1 : (!quake.veq<2>, !cc.ptr>) -> !quake.veq<2> return } - cc.global constant @__nvqpp_rodata_init_state.1 (dense<[0.707106769, 0.707106769, 0.000000e+00, 0.000000e+00]> : tensor<4xf32>) : !cc.array + cc.global constant @__nvqpp_rodata_init_state.1 (dense<[0.707106769, 0.707106769, 0.000000e+00, 0.000000e+00]> : tensor<4xf32>) : !cc.array {sym_visibility = "private"} // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_real_array_param._Z21test_real_array_paramSt6vectorIfSaIfEE() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = arith.constant 0.78539816339744839 : f64 diff --git a/test/Transforms/UnitarySynthesis/adjoint_test.qke b/test/Transforms/UnitarySynthesis/adjoint_test.qke index 787f91c30d..58122dfb46 100644 --- a/test/Transforms/UnitarySynthesis/adjoint_test.qke +++ b/test/Transforms/UnitarySynthesis/adjoint_test.qke @@ -17,8 +17,8 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp quake.h %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__custom_s_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> - cc.global constant @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp__mlirgen__custom_s_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} } // CHECK-LABEL: func.func private @__nvqpp__mlirgen__custom_s_generator_1.kernel( diff --git a/test/Transforms/UnitarySynthesis/basic_test.qke b/test/Transforms/UnitarySynthesis/basic_test.qke index 6bf20f140f..118c899b0b 100644 --- a/test/Transforms/UnitarySynthesis/basic_test.qke +++ b/test/Transforms/UnitarySynthesis/basic_test.qke @@ -14,7 +14,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__k1 = "__nvqpp__ml quake.custom_op @__nvqpp__mlirgen__custom_x_generator_1.rodata %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} } // CHECK-LABEL: func.func private @__nvqpp__mlirgen__custom_x_generator_1.kernel( diff --git a/test/Transforms/UnitarySynthesis/bell_pair.qke b/test/Transforms/UnitarySynthesis/bell_pair.qke index f5e2e494f6..0877b0fe6b 100644 --- a/test/Transforms/UnitarySynthesis/bell_pair.qke +++ b/test/Transforms/UnitarySynthesis/bell_pair.qke @@ -17,8 +17,8 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__bell = "__nvqpp__ quake.custom_op @__nvqpp__mlirgen__custom_x_generator_1.rodata [%1] %2 : (!quake.ref, !quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__custom_h_generator_1.rodata (dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> - cc.global constant @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp__mlirgen__custom_h_generator_1.rodata (dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} } // CHECK-LABEL: func.func private @__nvqpp__mlirgen__custom_h_generator_1.kernel( diff --git a/test/Transforms/UnitarySynthesis/random_unitary_1.qke b/test/Transforms/UnitarySynthesis/random_unitary_1.qke index 77e8f0711c..f1d8507922 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_1.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_1.qke @@ -14,7 +14,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel1 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op1_generator_1.rodata %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op1_generator_1.rodata (dense<[(-0.35004537000000002,0.66093880000000005), (0.52346031000000004,-0.40818800999999999), (-0.021867350000000001,0.66343799000000003), (-0.32826912000000003,0.67202026999999998)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp__mlirgen__op1_generator_1.rodata (dense<[(-0.35004537000000002,0.66093880000000005), (0.52346031000000004,-0.40818800999999999), (-0.021867350000000001,0.66343799000000003), (-0.32826912000000003,0.67202026999999998)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel1() attributes {"cudaq-entrypoint"} { diff --git a/test/Transforms/UnitarySynthesis/random_unitary_2.qke b/test/Transforms/UnitarySynthesis/random_unitary_2.qke index da85f4db02..00352d7165 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_2.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_2.qke @@ -14,7 +14,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel2 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op2_generator_1.rodata %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op2_generator_1.rodata (dense<[(0.74299870999999995,0.28281495000000001), (-0.46740644999999997,-0.38665209), (-0.39644517000000001,0.45912944999999999), (-0.68548675999999997,0.40266522999999999)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp__mlirgen__op2_generator_1.rodata (dense<[(0.74299870999999995,0.28281495000000001), (-0.46740644999999997,-0.38665209), (-0.39644517000000001,0.45912944999999999), (-0.68548675999999997,0.40266522999999999)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel2() attributes {"cudaq-entrypoint"} { diff --git a/test/Transforms/UnitarySynthesis/random_unitary_3.qke b/test/Transforms/UnitarySynthesis/random_unitary_3.qke index 8fa6ec1b1a..25f9425ef4 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_3.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_3.qke @@ -14,7 +14,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel3 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op3_generator_1.rodata %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op3_generator_1.rodata (dense<[(0.084676189999999998,-0.65461771000000002), (0.74164005,0.1194807), (0.40327485000000002,0.63377835000000005), (0.56763923999999999,-0.33686808000000001)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant @__nvqpp__mlirgen__op3_generator_1.rodata (dense<[(0.084676189999999998,-0.65461771000000002), (0.74164005,0.1194807), (0.40327485000000002,0.63377835000000005), (0.56763923999999999,-0.33686808000000001)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel3() attributes {"cudaq-entrypoint"} { diff --git a/test/Transforms/UnitarySynthesis/random_unitary_4.qke b/test/Transforms/UnitarySynthesis/random_unitary_4.qke index 0d75db2ac4..73db26bda3 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_4.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_4.qke @@ -16,7 +16,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel1 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op1_generator_2.rodata %1, %2 : (!quake.ref, !quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op1_generator_2.rodata (dense<[(-0.25534141999999999,0.045629179999999998), (0.11619328,0.79785479999999998), (0.19980911000000001,-0.24754117), (0.052455160000000001,0.42272180999999998), (0.48212336,-0.35275169000000001), (0.47307302000000001,2.047710e-01), (0.38804407000000002,0.34346750999999998), (-0.30236461999999997,-0.13199084), (0.53000373000000001,-0.052047940000000001), (-0.055464520000000003,0.044808380000000002), (-0.39853872000000001,-0.60358142999999997), (-0.40979785000000002,0.1422147), (0.20174057000000001,0.50152752), (0.042562830000000003,-0.27803220000000001), (0.14896845,0.29140401999999999), (-0.16938781,0.70203793000000003)]> : tensor<16xcomplex>) : !cc.array x 16> + cc.global constant @__nvqpp__mlirgen__op1_generator_2.rodata (dense<[(-0.25534141999999999,0.045629179999999998), (0.11619328,0.79785479999999998), (0.19980911000000001,-0.24754117), (0.052455160000000001,0.42272180999999998), (0.48212336,-0.35275169000000001), (0.47307302000000001,2.047710e-01), (0.38804407000000002,0.34346750999999998), (-0.30236461999999997,-0.13199084), (0.53000373000000001,-0.052047940000000001), (-0.055464520000000003,0.044808380000000002), (-0.39853872000000001,-0.60358142999999997), (-0.40979785000000002,0.1422147), (0.20174057000000001,0.50152752), (0.042562830000000003,-0.27803220000000001), (0.14896845,0.29140401999999999), (-0.16938781,0.70203793000000003)]> : tensor<16xcomplex>) : !cc.array x 16> {sym_visibility = "private"} } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel1() attributes {"cudaq-entrypoint"} { diff --git a/test/Transforms/UnitarySynthesis/random_unitary_5.qke b/test/Transforms/UnitarySynthesis/random_unitary_5.qke index 0da3aa0392..2503beac00 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_5.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_5.qke @@ -16,7 +16,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel2 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op2_generator_2.rodata %1, %2 : (!quake.ref, !quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op2_generator_2.rodata (dense<[(0.18897759,0.33963024000000003), (0.12335641999999999,-0.48243450999999998), (0.42873799000000001,-0.22386284000000001), (-0.38231686999999998,-0.46998072000000002), (0.26665664,0.31917547000000002), (0.66539470999999994,0.25221665999999998), (-0.47503402,-0.12900718), (-0.26305423,0.095708849999999998), (-0.1821702,0.14533362999999999), (0.18060332000000001,-0.34169106999999999), (1.314040e-03,-0.64370212999999998), (0.54215897999999996,0.29670066), (-0.30045970999999999,0.72895551000000003), (-0.26715635999999998,-0.15790472999999999), (-0.069665530000000003,0.32335976999999999), (-0.13738248,0.39211302999999997)]> : tensor<16xcomplex>) : !cc.array x 16> + cc.global constant @__nvqpp__mlirgen__op2_generator_2.rodata (dense<[(0.18897759,0.33963024000000003), (0.12335641999999999,-0.48243450999999998), (0.42873799000000001,-0.22386284000000001), (-0.38231686999999998,-0.46998072000000002), (0.26665664,0.31917547000000002), (0.66539470999999994,0.25221665999999998), (-0.47503402,-0.12900718), (-0.26305423,0.095708849999999998), (-0.1821702,0.14533362999999999), (0.18060332000000001,-0.34169106999999999), (1.314040e-03,-0.64370212999999998), (0.54215897999999996,0.29670066), (-0.30045970999999999,0.72895551000000003), (-0.26715635999999998,-0.15790472999999999), (-0.069665530000000003,0.32335976999999999), (-0.13738248,0.39211302999999997)]> : tensor<16xcomplex>) : !cc.array x 16> {sym_visibility = "private"} } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel2() attributes {"cudaq-entrypoint"} { diff --git a/test/Translate/translate_openqasm2_loop.cpp b/test/Translate/translate_openqasm2_loop.cpp index 8cb1504b2b..d2d920e00b 100644 --- a/test/Translate/translate_openqasm2_loop.cpp +++ b/test/Translate/translate_openqasm2_loop.cpp @@ -51,5 +51,5 @@ int main() { // CHECK: cx var0[2], var0[3]; // CHECK: cx var0[3], var0[4]; // CHECK: ccx var0[0], var0[2], var0[1]; -// CHECK: creg var12[5]; -// CHECK: measure var0 -> var12; +// CHECK: creg var6[5]; +// CHECK: measure var0 -> var6; From fec4e343369695d62eda23fb506c257f449f8717 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 15 Nov 2024 11:57:09 -0800 Subject: [PATCH 03/47] Fix failing tests and format Signed-off-by: Anna Gringauze --- python/tests/mlir/custom_op_builder.py | 2 +- .../translate_openqasm2_custom_operation.cpp | 59 ------------------- 2 files changed, 1 insertion(+), 60 deletions(-) delete mode 100644 test/Translate/translate_openqasm2_custom_operation.cpp diff --git a/python/tests/mlir/custom_op_builder.py b/python/tests/mlir/custom_op_builder.py index 67ad888e58..a31b722e63 100644 --- a/python/tests/mlir/custom_op_builder.py +++ b/python/tests/mlir/custom_op_builder.py @@ -82,4 +82,4 @@ def register_custom_operations(matrix): # CHECK: } # CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_0_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} # CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_1_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_2_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} \ No newline at end of file +# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_2_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} diff --git a/test/Translate/translate_openqasm2_custom_operation.cpp b/test/Translate/translate_openqasm2_custom_operation.cpp deleted file mode 100644 index dd1a397ad1..0000000000 --- a/test/Translate/translate_openqasm2_custom_operation.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * - * All rights reserved. * - * * - * This source code and the accompanying materials are made available under * - * the terms of the Apache License 2.0 which accompanies this distribution. * - ******************************************************************************/ - -// RUN: cudaq-quake %s | cudaq-translate --convert-to=openqasm2 | FileCheck %s - -#include - -CUDAQ_REGISTER_OPERATION(custom_h, 1, 0, - {M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2}) - -CUDAQ_REGISTER_OPERATION(custom_cnot, 2, 0, - {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0}) - -__qpu__ void bell_pair() { - cudaq::qubit q, r; - custom_h(q); - custom_cnot(q, r); -} - -// CHECK: // Code generated by NVIDIA's nvq++ compiler -// CHECK: OPENQASM 2.0; - -// CHECK: include "qelib1.inc"; - -// CHECK: gate Z9bell_pairv { -// CHECK: } - -// CHECK: qreg var0[1]; -// CHECK: qreg var1[1]; -// CHECK: rz(3.141593e+00) var0[0]; -// CHECK: ry(1.570796e+00) var0[0]; -// CHECK: u1(3.141593e+00) var0[0]; -// CHECK: rz(-3.141593e+00) var0[0]; -// CHECK: ry(1.570796e+00) var1[0]; -// CHECK: rz(2.725460e+00) var1[0]; -// CHECK: rz(-3.406437e+00) var0[0]; -// CHECK: rz(3.999978e-01) var0[0]; -// CHECK: rx(1.570796e+00) var0[0]; -// CHECK: rx(1.570796e+00) var1[0]; -// CHECK: cx var1[0], var0[0]; -// CHECK: rz(-3.141593e+00) var0[0]; -// CHECK: cx var1[0], var0[0]; -// CHECK: rx(-1.570796e+00) var1[0]; -// CHECK: rx(-1.570796e+00) var0[0]; -// CHECK: cx var1[0], var0[0]; -// CHECK: rz(-1.570796e+00) var0[0]; -// CHECK: cx var1[0], var0[0]; -// CHECK: rz(1.154664e+00) var1[0]; -// CHECK: ry(1.570796e+00) var1[0]; -// CHECK: rz(1.893954e+00) var0[0]; -// CHECK: ry(3.141593e+00) var0[0]; -// CHECK: rz(3.329597e+00) var0[0]; -// CHECK: u1(1.570796e+00) var0[0]; -// CHECK: rz(-1.570796e+00) var0[0]; \ No newline at end of file From fc810762b549c31a972a10051ef36057e4671358 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 15 Nov 2024 13:42:53 -0800 Subject: [PATCH 04/47] Address CR comments Signed-off-by: Anna Gringauze --- include/cudaq/Optimizer/Dialect/CC/CCOps.td | 5 +- include/cudaq/Optimizer/Transforms/Passes.td | 4 +- lib/Optimizer/Dialect/CC/CCOps.cpp | 73 +++++++++++++++++++ lib/Optimizer/Transforms/StatePreparation.cpp | 4 +- python/tests/mlir/custom_op_builder.py | 6 +- python/tests/mlir/custom_operation.py | 8 +- runtime/test/test_argument_conversion.cpp | 4 +- test/AST-Quake/custom_op_concrete_matrix.cpp | 4 +- test/AST-Quake/initialization_list.cpp | 2 +- test/Quake-QIR/custom_operation.qke | 4 +- test/Quake/add_dealloc-1.qke | 4 +- test/Quake/delete_states.qke | 12 +-- test/Quake/lift_array.qke | 6 +- test/Quake/state_prep.qke | 8 +- .../UnitarySynthesis/adjoint_test.qke | 4 +- .../UnitarySynthesis/basic_test.qke | 2 +- .../Transforms/UnitarySynthesis/bell_pair.qke | 4 +- .../UnitarySynthesis/random_unitary_1.qke | 2 +- .../UnitarySynthesis/random_unitary_2.qke | 2 +- .../UnitarySynthesis/random_unitary_3.qke | 2 +- .../UnitarySynthesis/random_unitary_4.qke | 2 +- .../UnitarySynthesis/random_unitary_5.qke | 2 +- 22 files changed, 117 insertions(+), 47 deletions(-) diff --git a/include/cudaq/Optimizer/Dialect/CC/CCOps.td b/include/cudaq/Optimizer/Dialect/CC/CCOps.td index 31baeb640e..7b76067485 100644 --- a/include/cudaq/Optimizer/Dialect/CC/CCOps.td +++ b/include/cudaq/Optimizer/Dialect/CC/CCOps.td @@ -919,10 +919,7 @@ def cc_GlobalOp : CCOp<"global", [IsolatedFromAbove, Symbol]> { UnitAttr:$external ); - let assemblyFormat = [{ - ( `external` $external^ )? ( `constant` $constant^ )? - $sym_name `(`$value`)` `:` qualified($global_type) attr-dict - }]; + let hasCustomAssemblyFormat = 1; let builders = [ OpBuilder<(ins diff --git a/include/cudaq/Optimizer/Transforms/Passes.td b/include/cudaq/Optimizer/Transforms/Passes.td index 1c3640dd4c..15724c6484 100644 --- a/include/cudaq/Optimizer/Transforms/Passes.td +++ b/include/cudaq/Optimizer/Transforms/Passes.td @@ -407,7 +407,7 @@ def GetConcreteMatrix : Pass<"get-concrete-matrix", "mlir::func::FuncOp"> { return } - cc.global constant @__nvqpp__mlirgen__function_foo_generator_1.bar.rodata_0 ((dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__function_foo_generator_1.bar.rodata_0 ((dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> } ``` @@ -816,7 +816,7 @@ def StatePreparation : Pass<"state-prep", "mlir::ModuleOp"> { %2 = quake.init_state %1, %0 : (!quake.veq<2>, !cc.ptr x 4>>) -> !quake.veq<2> return } - cc.global constant @foo.rodata_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @foo.rodata_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> } ``` Will be rewritten to: diff --git a/lib/Optimizer/Dialect/CC/CCOps.cpp b/lib/Optimizer/Dialect/CC/CCOps.cpp index 67a7c57ccf..9d539640ac 100644 --- a/lib/Optimizer/Dialect/CC/CCOps.cpp +++ b/lib/Optimizer/Dialect/CC/CCOps.cpp @@ -987,6 +987,79 @@ void cudaq::cc::ExtractValueOp::getCanonicalizationPatterns( patterns.add(context); } +//===----------------------------------------------------------------------===// +// GlobalOp +//===----------------------------------------------------------------------===// + +ParseResult cudaq::cc::GlobalOp::parse(OpAsmParser &parser, + OperationState &result) { + // Check for the `extern` optional keyword first. + if (succeeded(parser.parseOptionalKeyword("extern"))) + result.addAttribute(getExternalAttrName(result.name), + parser.getBuilder().getUnitAttr()); + + // Check for the `constant` optional keyword second. + if (succeeded(parser.parseOptionalKeyword("constant"))) + result.addAttribute(getConstantAttrName(result.name), + parser.getBuilder().getUnitAttr()); + + // Check for the visibility optional keyword third. + StringRef visibility; + if (parser.parseOptionalKeyword(&visibility, {"public", "private", "nested"})) + return failure(); + + StringAttr visibilityAttr = parser.getBuilder().getStringAttr(visibility); + result.addAttribute(SymbolTable::getVisibilityAttrName(), visibilityAttr); + + // Parse the rest of the global. + // @ ( ) : + StringAttr name; + if (parser.parseSymbolName(name, getSymNameAttrName(result.name), + result.attributes)) + return failure(); + if (succeeded(parser.parseOptionalLParen())) { + Attribute value; + if (parser.parseAttribute(value, getValueAttrName(result.name), + result.attributes) || + parser.parseRParen()) + return failure(); + } + SmallVector types; + if (parser.parseOptionalColonTypeList(types) || + parser.parseOptionalAttrDict(result.attributes)) + return failure(); + if (types.size() > 1) + return parser.emitError(parser.getNameLoc(), "expected zero or one type"); + result.addAttribute(getGlobalTypeAttrName(result.name), + TypeAttr::get(types[0])); + return success(); +} + +void cudaq::cc::GlobalOp::print(OpAsmPrinter &p) { + p << ' '; + if (getExternal()) + p << "extern "; + if (getConstant()) + p << "constant "; + + if (auto visibility = getSymVisibility()) + if (visibility.has_value()) + p << visibility.value().str() << ' '; + + p.printSymbolName(getSymName()); + if (auto value = getValue()) { + p << " ("; + p.printAttribute(*value); + p << ")"; + } + p << " : " << getGlobalType(); + + p.printOptionalAttrDict((*this)->getAttrs(), + {getSymNameAttrName(), getValueAttrName(), + getGlobalTypeAttrName(), getConstantAttrName(), + getExternalAttrName(), getSymVisibilityAttrName()}); +} + //===----------------------------------------------------------------------===// // StdvecDataOp //===----------------------------------------------------------------------===// diff --git a/lib/Optimizer/Transforms/StatePreparation.cpp b/lib/Optimizer/Transforms/StatePreparation.cpp index 42685f5252..8c6c615368 100644 --- a/lib/Optimizer/Transforms/StatePreparation.cpp +++ b/lib/Optimizer/Transforms/StatePreparation.cpp @@ -296,10 +296,10 @@ class StateDecomposer { /// !cc.ptr x 4>>) -> !quake.veq<2> /// return /// } -/// cc.global constant @foo.rodata_0 (dense<[(0.707106769,0.000000e+00), +/// cc.global constant private @foo.rodata_0 +/// (dense<[(0.707106769,0.000000e+00), /// (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), /// (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : -/// {sym_visibility = "private"} /// !cc.array x 4> /// } /// ``` diff --git a/python/tests/mlir/custom_op_builder.py b/python/tests/mlir/custom_op_builder.py index a31b722e63..b0d44e2eec 100644 --- a/python/tests/mlir/custom_op_builder.py +++ b/python/tests/mlir/custom_op_builder.py @@ -80,6 +80,6 @@ def register_custom_operations(matrix): # CHECK: quake.custom_op @__nvqpp__mlirgen__foo_2_generator_1.rodata {{\[}}%[[VAL_4]]] %[[VAL_3]] : (!quake.veq<2>, !quake.veq<1>) -> () # CHECK: return # CHECK: } -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_0_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_1_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__foo_2_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__foo_0_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__foo_1_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__foo_2_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> diff --git a/python/tests/mlir/custom_operation.py b/python/tests/mlir/custom_operation.py index 9fbb119822..3a35142539 100644 --- a/python/tests/mlir/custom_operation.py +++ b/python/tests/mlir/custom_operation.py @@ -35,8 +35,8 @@ def bell(): # CHECK: quake.custom_op @__nvqpp__mlirgen__custom_x_generator_1.rodata {{\[}}%[[VAL_1]]] %[[VAL_2]] : (!quake.ref, !quake.ref) -> () # CHECK: return # CHECK: } -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__custom_h_generator_1.rodata(dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__custom_x_generator_1.rodata(dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__custom_h_generator_1.rodata(dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__custom_x_generator_1.rodata(dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> def test_custom_adjoint(): @@ -64,5 +64,5 @@ def kernel(): # CHECK: quake.h %[[VAL_0]] : (!quake.ref) -> () # CHECK: return # CHECK: } -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__custom_s_generator_1.rodata(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} -# CHECK-DAG: cc.global constant @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__custom_s_generator_1.rodata(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> diff --git a/runtime/test/test_argument_conversion.cpp b/runtime/test/test_argument_conversion.cpp index 4719430537..987bfd4c34 100644 --- a/runtime/test/test_argument_conversion.cpp +++ b/runtime/test/test_argument_conversion.cpp @@ -388,7 +388,7 @@ void test_state(mlir::MLIRContext *ctx) { // CHECK: %[[VAL_5:.*]] = func.call @__nvqpp_cudaq_state_createFromData_fp64(%[[VAL_4]], %[[VAL_2]]) : (!cc.ptr, i64) -> !cc.ptr // CHECK: %[[VAL_6:.*]] = cc.cast %[[VAL_5]] : (!cc.ptr) -> !cc.ptr // CHECK: } -// CHECK-DAG: cc.global constant @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} +// CHECK-DAG: cc.global constant private @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> // CHECK-DAG: func.func private @__nvqpp_cudaq_state_createFromData_fp64(!cc.ptr, i64) -> !cc.ptr // clang-format on } @@ -498,7 +498,7 @@ void test_combinations(mlir::MLIRContext *ctx) { // CHECK: %[[VAL_5:.*]] = func.call @__nvqpp_cudaq_state_createFromData_fp64(%[[VAL_4]], %[[VAL_2]]) : (!cc.ptr, i64) -> !cc.ptr // CHECK: %[[VAL_6:.*]] = cc.cast %[[VAL_5]] : (!cc.ptr) -> !cc.ptr // CHECK: } -// CHECK-DAG: cc.global constant @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} +// CHECK-DAG: cc.global constant private @[[VAL_GC]] (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> // CHECK-DAG: func.func private @__nvqpp_cudaq_state_createFromData_fp64(!cc.ptr, i64) -> !cc.ptr // CHECK-LABEL: cc.arg_subst[2] { // CHECK: %[[VAL_0:.*]] = cc.alloca !cc.array diff --git a/test/AST-Quake/custom_op_concrete_matrix.cpp b/test/AST-Quake/custom_op_concrete_matrix.cpp index f0a849f28d..0579faa996 100644 --- a/test/AST-Quake/custom_op_concrete_matrix.cpp +++ b/test/AST-Quake/custom_op_concrete_matrix.cpp @@ -33,5 +33,5 @@ __qpu__ void kernel_1() { // CHECK: return // CHECK: } -// CHECK-DAG: cc.global constant @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}}(dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} -// CHECK-DAG: cc.global constant @__nvqpp__mlirgen__function_custom_cnot_generator_2._Z23custom_cnot_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}}(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<16xcomplex>) : !cc.array x 16> {sym_visibility = "private"} +// CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}}(dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +// CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__function_custom_cnot_generator_2._Z23custom_cnot_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}}(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<16xcomplex>) : !cc.array x 16> diff --git a/test/AST-Quake/initialization_list.cpp b/test/AST-Quake/initialization_list.cpp index 8067ededd7..44285eb88e 100644 --- a/test/AST-Quake/initialization_list.cpp +++ b/test/AST-Quake/initialization_list.cpp @@ -44,5 +44,5 @@ __qpu__ void g() { // CHECK: return // CHECK: } -// CHECK: cc.global constant @__nvqpp__rodata_init_0(dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00]> : tensor<4xf64>) : !cc.array {sym_visibility = "private"} +// CHECK: cc.global constant private @__nvqpp__rodata_init_0(dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00]> : tensor<4xf64>) : !cc.array diff --git a/test/Quake-QIR/custom_operation.qke b/test/Quake-QIR/custom_operation.qke index 0127901521..ceb1b0c26c 100644 --- a/test/Quake-QIR/custom_operation.qke +++ b/test/Quake-QIR/custom_operation.qke @@ -19,8 +19,8 @@ module { %measOut = quake.mz %0 : (!quake.ref) -> !quake.measure return } - cc.global constant @__nvqpp__mlirgen__function_custom_s_generator_1._Z20custom_s_generator_1RKSt6vectorIdSaIdEE.rodata_0 (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} - cc.global constant @__nvqpp__mlirgen__function_custom_s_adj_generator_1._Z24custom_s_adj_generator_1RKSt6vectorIdSaIdEE.rodata_1 (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__function_custom_s_generator_1._Z20custom_s_generator_1RKSt6vectorIdSaIdEE.rodata_0 (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant private @__nvqpp__mlirgen__function_custom_s_adj_generator_1._Z24custom_s_adj_generator_1RKSt6vectorIdSaIdEE.rodata_1 (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> } diff --git a/test/Quake/add_dealloc-1.qke b/test/Quake/add_dealloc-1.qke index 454f976fe3..02d5221310 100644 --- a/test/Quake/add_dealloc-1.qke +++ b/test/Quake/add_dealloc-1.qke @@ -31,7 +31,7 @@ module { } {invariant} return } - cc.global constant @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 0.000000e+00, 5.000000e-01, 5.000000e-01]> : tensor<4xf64>) : !cc.array {sym_visibility = "private"} + cc.global constant private @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 0.000000e+00, 5.000000e-01, 5.000000e-01]> : tensor<4xf64>) : !cc.array } // CHECK-LABEL: func.func @__nvqpp__mlirgen__FromState() { @@ -41,5 +41,5 @@ module { // CHECK: quake.dealloc %[[VAL_5]] : !quake.veq<4> // CHECK: return // CHECK: } -// CHECK: cc.global constant @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 0.000000e+00, 5.000000e-01, 5.000000e-01]> : tensor<4xf64>) : !cc.array {sym_visibility = "private"} +// CHECK: cc.global constant private @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 0.000000e+00, 5.000000e-01, 5.000000e-01]> : tensor<4xf64>) : !cc.array diff --git a/test/Quake/delete_states.qke b/test/Quake/delete_states.qke index 634161b1e0..bee6a09b91 100644 --- a/test/Quake/delete_states.qke +++ b/test/Quake/delete_states.qke @@ -23,8 +23,8 @@ module { return } func.func private @__nvqpp_cudaq_state_numberOfQubits(!cc.ptr) -> i64 - cc.global constant @function_test_state_param._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00 -,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} + cc.global constant private @function_test_state_param._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00 +,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> func.func private @__nvqpp_cudaq_state_createFromData_fp32(!cc.ptr, i64) -> !cc.ptr // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_state_param._Z16test_state_paramPN5cudaq5stateE() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { @@ -35,7 +35,7 @@ module { // CHECK: %[[VAL_3:.*]] = quake.alloca !quake.veq<3> // CHECK: %[[VAL_4:.*]] = quake.init_state %[[VAL_3]], %[[VAL_2]] : (!quake.veq<3>, !cc.ptr x 8>>) -> !quake.veq<3> // CHECK: } -// CHECK-DAG: cc.global constant @function_test_state_param._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} +// CHECK-DAG: cc.global constant private @function_test_state_param._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> func.func @__nvqpp__mlirgen__sub_kernel(%arg : !cc.ptr) attributes {"cudaq-kernel", no_this} { %0 = call @__nvqpp_cudaq_state_numberOfQubits(%arg) : (!cc.ptr) -> i64 @@ -56,8 +56,8 @@ module { return } - cc.global constant @function_test_state_param1._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00 -,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} + cc.global constant private @function_test_state_param1._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00 +,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> // CHECK: func.func @__nvqpp__mlirgen__sub_kernel(%[[VAL_ARG:.*]]: !cc.ptr) attributes {"cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = call @__nvqpp_cudaq_state_numberOfQubits(%[[VAL_ARG]]) : (!cc.ptr) -> i64 @@ -78,7 +78,7 @@ module { // CHECK: call @__nvqpp_cudaq_state_delete(%[[VAL_5]]) : (!cc.ptr) -> () // CHECK: return // CHECK: } -// CHECK-DAG: cc.global constant @function_test_state_param1._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> {sym_visibility = "private"} +// CHECK-DAG: cc.global constant private @function_test_state_param1._Z16test_state_paramPN5cudaq5stateE.rodata_synth_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<8xcomplex>) : !cc.array x 8> // CHECK-DAG: func.func private @__nvqpp_cudaq_state_delete(!cc.ptr) } diff --git a/test/Quake/lift_array.qke b/test/Quake/lift_array.qke index 1179aa6bd4..ab649f01bc 100644 --- a/test/Quake/lift_array.qke +++ b/test/Quake/lift_array.qke @@ -122,6 +122,6 @@ func.func @test2() -> !quake.veq<2> { // GLOBAL: return %[[VAL_2]] : !quake.veq<2> // GLOBAL: } -// GLOBAL-DAG: cc.global constant @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv.rodata_{{[0-9]+}} (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} -// GLOBAL-DAG: cc.global constant @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_1v.rodata_{{[0-9]+}} (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} -// GLOBAL-DAG: cc.global constant @test2.rodata_{{[0-9]+}} (dense<[1.000000e+00, 2.000000e+00, 6.000000e+00, 9.000000e+00]>" : tensor<4xf64>) : !cc.array {sym_visibility = "private"} +// GLOBAL-DAG: cc.global constant private @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv.rodata_{{[0-9]+}} (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +// GLOBAL-DAG: cc.global constant private @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_1v.rodata_{{[0-9]+}} (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +// GLOBAL-DAG: cc.global constant private @test2.rodata_{{[0-9]+}} (dense<[1.000000e+00, 2.000000e+00, 6.000000e+00, 9.000000e+00]>" : tensor<4xf64>) : !cc.array diff --git a/test/Quake/state_prep.qke b/test/Quake/state_prep.qke index 969f38ee44..ed4300ecba 100644 --- a/test/Quake/state_prep.qke +++ b/test/Quake/state_prep.qke @@ -15,7 +15,7 @@ module { %2 = quake.init_state %1, %0 : (!quake.veq<2>, !cc.ptr x 4>>) -> !quake.veq<2> return } - cc.global constant @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv.rodata_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv.rodata_0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_complex_constant_array._Z27test_complex_constant_arrayv() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = arith.constant 0.78539816339744839 : f64 @@ -37,7 +37,7 @@ module { %2 = quake.init_state %1, %0 : (!quake.veq<2>, !cc.ptr>) -> !quake.veq<2> return } - cc.global constant @__nvqpp__mlirgen__function_test_real_constant_array._Z24test_real_constant_arrayv.rodata_0 (dense<[0.70710678118654757, 0.70710678118654757, 0.000000e+00, 0.000000e+00]> : tensor<4xf64>) : !cc.array {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__function_test_real_constant_array._Z24test_real_constant_arrayv.rodata_0 (dense<[0.70710678118654757, 0.70710678118654757, 0.000000e+00, 0.000000e+00]> : tensor<4xf64>) : !cc.array // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_real_constant_array._Z24test_real_constant_arrayv() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = arith.constant 0.78539816339744839 : f64 @@ -60,7 +60,7 @@ module { %3 = quake.init_state %2, %1 : (!quake.veq<2>, !cc.ptr x ?>>) -> !quake.veq<2> return } - cc.global constant @__nvqpp_rodata_init_state.0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp_rodata_init_state.0 (dense<[(0.707106769,0.000000e+00), (0.707106769,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_complex_array_param._Z24test_complex_array_paramSt6vectorISt7complexIfESaIS1_EE() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = arith.constant 0.78539816339744839 : f64 @@ -83,7 +83,7 @@ module { %3 = quake.init_state %2, %1 : (!quake.veq<2>, !cc.ptr>) -> !quake.veq<2> return } - cc.global constant @__nvqpp_rodata_init_state.1 (dense<[0.707106769, 0.707106769, 0.000000e+00, 0.000000e+00]> : tensor<4xf32>) : !cc.array {sym_visibility = "private"} + cc.global constant private @__nvqpp_rodata_init_state.1 (dense<[0.707106769, 0.707106769, 0.000000e+00, 0.000000e+00]> : tensor<4xf32>) : !cc.array // CHECK-LABEL: func.func @__nvqpp__mlirgen__function_test_real_array_param._Z21test_real_array_paramSt6vectorIfSaIfEE() attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} { // CHECK: %[[VAL_0:.*]] = arith.constant 0.78539816339744839 : f64 diff --git a/test/Transforms/UnitarySynthesis/adjoint_test.qke b/test/Transforms/UnitarySynthesis/adjoint_test.qke index 58122dfb46..82a2049241 100644 --- a/test/Transforms/UnitarySynthesis/adjoint_test.qke +++ b/test/Transforms/UnitarySynthesis/adjoint_test.qke @@ -17,8 +17,8 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp quake.h %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__custom_s_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} - cc.global constant @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__custom_s_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant private @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> } // CHECK-LABEL: func.func private @__nvqpp__mlirgen__custom_s_generator_1.kernel( diff --git a/test/Transforms/UnitarySynthesis/basic_test.qke b/test/Transforms/UnitarySynthesis/basic_test.qke index 118c899b0b..dac166ad48 100644 --- a/test/Transforms/UnitarySynthesis/basic_test.qke +++ b/test/Transforms/UnitarySynthesis/basic_test.qke @@ -14,7 +14,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__k1 = "__nvqpp__ml quake.custom_op @__nvqpp__mlirgen__custom_x_generator_1.rodata %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> } // CHECK-LABEL: func.func private @__nvqpp__mlirgen__custom_x_generator_1.kernel( diff --git a/test/Transforms/UnitarySynthesis/bell_pair.qke b/test/Transforms/UnitarySynthesis/bell_pair.qke index 0877b0fe6b..806ae78faf 100644 --- a/test/Transforms/UnitarySynthesis/bell_pair.qke +++ b/test/Transforms/UnitarySynthesis/bell_pair.qke @@ -17,8 +17,8 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__bell = "__nvqpp__ quake.custom_op @__nvqpp__mlirgen__custom_x_generator_1.rodata [%1] %2 : (!quake.ref, !quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__custom_h_generator_1.rodata (dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} - cc.global constant @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__custom_h_generator_1.rodata (dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> + cc.global constant private @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> } // CHECK-LABEL: func.func private @__nvqpp__mlirgen__custom_h_generator_1.kernel( diff --git a/test/Transforms/UnitarySynthesis/random_unitary_1.qke b/test/Transforms/UnitarySynthesis/random_unitary_1.qke index f1d8507922..384aed8a07 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_1.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_1.qke @@ -14,7 +14,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel1 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op1_generator_1.rodata %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op1_generator_1.rodata (dense<[(-0.35004537000000002,0.66093880000000005), (0.52346031000000004,-0.40818800999999999), (-0.021867350000000001,0.66343799000000003), (-0.32826912000000003,0.67202026999999998)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__op1_generator_1.rodata (dense<[(-0.35004537000000002,0.66093880000000005), (0.52346031000000004,-0.40818800999999999), (-0.021867350000000001,0.66343799000000003), (-0.32826912000000003,0.67202026999999998)]> : tensor<4xcomplex>) : !cc.array x 4> } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel1() attributes {"cudaq-entrypoint"} { diff --git a/test/Transforms/UnitarySynthesis/random_unitary_2.qke b/test/Transforms/UnitarySynthesis/random_unitary_2.qke index 00352d7165..a3da08654b 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_2.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_2.qke @@ -14,7 +14,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel2 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op2_generator_1.rodata %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op2_generator_1.rodata (dense<[(0.74299870999999995,0.28281495000000001), (-0.46740644999999997,-0.38665209), (-0.39644517000000001,0.45912944999999999), (-0.68548675999999997,0.40266522999999999)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__op2_generator_1.rodata (dense<[(0.74299870999999995,0.28281495000000001), (-0.46740644999999997,-0.38665209), (-0.39644517000000001,0.45912944999999999), (-0.68548675999999997,0.40266522999999999)]> : tensor<4xcomplex>) : !cc.array x 4> } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel2() attributes {"cudaq-entrypoint"} { diff --git a/test/Transforms/UnitarySynthesis/random_unitary_3.qke b/test/Transforms/UnitarySynthesis/random_unitary_3.qke index 25f9425ef4..2488be141b 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_3.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_3.qke @@ -14,7 +14,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel3 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op3_generator_1.rodata %0 : (!quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op3_generator_1.rodata (dense<[(0.084676189999999998,-0.65461771000000002), (0.74164005,0.1194807), (0.40327485000000002,0.63377835000000005), (0.56763923999999999,-0.33686808000000001)]> : tensor<4xcomplex>) : !cc.array x 4> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__op3_generator_1.rodata (dense<[(0.084676189999999998,-0.65461771000000002), (0.74164005,0.1194807), (0.40327485000000002,0.63377835000000005), (0.56763923999999999,-0.33686808000000001)]> : tensor<4xcomplex>) : !cc.array x 4> } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel3() attributes {"cudaq-entrypoint"} { diff --git a/test/Transforms/UnitarySynthesis/random_unitary_4.qke b/test/Transforms/UnitarySynthesis/random_unitary_4.qke index 73db26bda3..697056ce5a 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_4.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_4.qke @@ -16,7 +16,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel1 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op1_generator_2.rodata %1, %2 : (!quake.ref, !quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op1_generator_2.rodata (dense<[(-0.25534141999999999,0.045629179999999998), (0.11619328,0.79785479999999998), (0.19980911000000001,-0.24754117), (0.052455160000000001,0.42272180999999998), (0.48212336,-0.35275169000000001), (0.47307302000000001,2.047710e-01), (0.38804407000000002,0.34346750999999998), (-0.30236461999999997,-0.13199084), (0.53000373000000001,-0.052047940000000001), (-0.055464520000000003,0.044808380000000002), (-0.39853872000000001,-0.60358142999999997), (-0.40979785000000002,0.1422147), (0.20174057000000001,0.50152752), (0.042562830000000003,-0.27803220000000001), (0.14896845,0.29140401999999999), (-0.16938781,0.70203793000000003)]> : tensor<16xcomplex>) : !cc.array x 16> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__op1_generator_2.rodata (dense<[(-0.25534141999999999,0.045629179999999998), (0.11619328,0.79785479999999998), (0.19980911000000001,-0.24754117), (0.052455160000000001,0.42272180999999998), (0.48212336,-0.35275169000000001), (0.47307302000000001,2.047710e-01), (0.38804407000000002,0.34346750999999998), (-0.30236461999999997,-0.13199084), (0.53000373000000001,-0.052047940000000001), (-0.055464520000000003,0.044808380000000002), (-0.39853872000000001,-0.60358142999999997), (-0.40979785000000002,0.1422147), (0.20174057000000001,0.50152752), (0.042562830000000003,-0.27803220000000001), (0.14896845,0.29140401999999999), (-0.16938781,0.70203793000000003)]> : tensor<16xcomplex>) : !cc.array x 16> } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel1() attributes {"cudaq-entrypoint"} { diff --git a/test/Transforms/UnitarySynthesis/random_unitary_5.qke b/test/Transforms/UnitarySynthesis/random_unitary_5.qke index 2503beac00..4ae6e1a889 100644 --- a/test/Transforms/UnitarySynthesis/random_unitary_5.qke +++ b/test/Transforms/UnitarySynthesis/random_unitary_5.qke @@ -16,7 +16,7 @@ module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel2 = "__nvqp quake.custom_op @__nvqpp__mlirgen__op2_generator_2.rodata %1, %2 : (!quake.ref, !quake.ref) -> () return } - cc.global constant @__nvqpp__mlirgen__op2_generator_2.rodata (dense<[(0.18897759,0.33963024000000003), (0.12335641999999999,-0.48243450999999998), (0.42873799000000001,-0.22386284000000001), (-0.38231686999999998,-0.46998072000000002), (0.26665664,0.31917547000000002), (0.66539470999999994,0.25221665999999998), (-0.47503402,-0.12900718), (-0.26305423,0.095708849999999998), (-0.1821702,0.14533362999999999), (0.18060332000000001,-0.34169106999999999), (1.314040e-03,-0.64370212999999998), (0.54215897999999996,0.29670066), (-0.30045970999999999,0.72895551000000003), (-0.26715635999999998,-0.15790472999999999), (-0.069665530000000003,0.32335976999999999), (-0.13738248,0.39211302999999997)]> : tensor<16xcomplex>) : !cc.array x 16> {sym_visibility = "private"} + cc.global constant private @__nvqpp__mlirgen__op2_generator_2.rodata (dense<[(0.18897759,0.33963024000000003), (0.12335641999999999,-0.48243450999999998), (0.42873799000000001,-0.22386284000000001), (-0.38231686999999998,-0.46998072000000002), (0.26665664,0.31917547000000002), (0.66539470999999994,0.25221665999999998), (-0.47503402,-0.12900718), (-0.26305423,0.095708849999999998), (-0.1821702,0.14533362999999999), (0.18060332000000001,-0.34169106999999999), (1.314040e-03,-0.64370212999999998), (0.54215897999999996,0.29670066), (-0.30045970999999999,0.72895551000000003), (-0.26715635999999998,-0.15790472999999999), (-0.069665530000000003,0.32335976999999999), (-0.13738248,0.39211302999999997)]> : tensor<16xcomplex>) : !cc.array x 16> } // CHECK-LABEL: func.func @__nvqpp__mlirgen__kernel2() attributes {"cudaq-entrypoint"} { From 8918c924fbded38681903261917ffb00eb6147ca Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 15 Nov 2024 13:54:49 -0800 Subject: [PATCH 05/47] Address CR comments Signed-off-by: Anna Gringauze --- targettests/execution/custom_operation_adj.cpp | 12 ++++++------ targettests/execution/custom_operation_basic.cpp | 12 ++++++------ targettests/execution/graph_coloring-1.cpp | 4 ++-- targettests/execution/graph_coloring.cpp | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/targettests/execution/custom_operation_adj.cpp b/targettests/execution/custom_operation_adj.cpp index 9541dd492a..314527fae5 100644 --- a/targettests/execution/custom_operation_adj.cpp +++ b/targettests/execution/custom_operation_adj.cpp @@ -7,13 +7,13 @@ ******************************************************************************/ // clang-format off -// RUN: nvq++ -std=c++17 --enable-mlir %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target anyon --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target braket --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target ionq --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ -std=c++17 --enable-mlir %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target anyon --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target braket --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target ionq --emulate %s -o %t && %t | FileCheck %s // RUN: nvq++ %cpp_std --target iqm --iqm-machine Apollo --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target oqc --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target quantinuum --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target oqc --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target quantinuum --emulate %s -o %t && %t | FileCheck %s // clang-format on #include diff --git a/targettests/execution/custom_operation_basic.cpp b/targettests/execution/custom_operation_basic.cpp index 9c5724c390..d567bd968a 100644 --- a/targettests/execution/custom_operation_basic.cpp +++ b/targettests/execution/custom_operation_basic.cpp @@ -7,13 +7,13 @@ ******************************************************************************/ // clang-format off -// RUN: nvq++ -std=c++17 --enable-mlir %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target anyon --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target braket --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target ionq --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ -std=c++17 --enable-mlir %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target anyon --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target braket --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target ionq --emulate %s -o %t && %t | FileCheck %s // RUN: nvq++ %cpp_std --target iqm --iqm-machine Apollo --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target oqc --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ %cpp_std --target quantinuum --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target oqc --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %cpp_std --target quantinuum --emulate %s -o %t && %t | FileCheck %s // clang-format on #include diff --git a/targettests/execution/graph_coloring-1.cpp b/targettests/execution/graph_coloring-1.cpp index 794e607f14..88b5fae654 100644 --- a/targettests/execution/graph_coloring-1.cpp +++ b/targettests/execution/graph_coloring-1.cpp @@ -8,8 +8,8 @@ // REQUIRES: c++20 // clang-format off -// RUN: nvq++ --target braket --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target quantinuum --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %s -o %t --target braket --emulate && %t FileCheck %s +// RUN: nvq++ %s -o %t --target quantinuum --emulate && %t | FileCheck %s // clang-format on #include diff --git a/targettests/execution/graph_coloring.cpp b/targettests/execution/graph_coloring.cpp index e3ab5c5f40..93147e4a72 100644 --- a/targettests/execution/graph_coloring.cpp +++ b/targettests/execution/graph_coloring.cpp @@ -8,8 +8,8 @@ // REQUIRES: c++20 // clang-format off -// RUN: nvq++ --target braket --emulate %s -o %t && %t | FileCheck %s -// RUN: nvq++ --target quantinuum --emulate %s -o %t && %t | FileCheck %s +// RUN: nvq++ %s -o %t --target braket --emulate && %t FileCheck %s +// RUN: nvq++ %s -o %t --target quantinuum --emulate && %t | FileCheck %s // clang-format on #include From 774d3373f98cbd9b7772338a223af88b35e2b738 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 15 Nov 2024 15:22:27 -0800 Subject: [PATCH 06/47] Fix failing tests Signed-off-by: Anna Gringauze --- python/tests/mlir/custom_op_builder.py | 6 +++--- python/tests/mlir/custom_operation.py | 8 ++++---- test/AST-Quake/custom_op_concrete_matrix.cpp | 4 ++-- test/AST-Quake/initialization_list.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/python/tests/mlir/custom_op_builder.py b/python/tests/mlir/custom_op_builder.py index b0d44e2eec..4e6b0a94b7 100644 --- a/python/tests/mlir/custom_op_builder.py +++ b/python/tests/mlir/custom_op_builder.py @@ -80,6 +80,6 @@ def register_custom_operations(matrix): # CHECK: quake.custom_op @__nvqpp__mlirgen__foo_2_generator_1.rodata {{\[}}%[[VAL_4]]] %[[VAL_3]] : (!quake.veq<2>, !quake.veq<1>) -> () # CHECK: return # CHECK: } -# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__foo_0_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> -# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__foo_1_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> -# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__foo_2_generator_1.rodata(dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__foo_0_generator_1.rodata (dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__foo_1_generator_1.rodata (dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__foo_2_generator_1.rodata (dense<[{{.*}}]> : tensor<4xcomplex>) : !cc.array x 4> diff --git a/python/tests/mlir/custom_operation.py b/python/tests/mlir/custom_operation.py index 3a35142539..37173373f5 100644 --- a/python/tests/mlir/custom_operation.py +++ b/python/tests/mlir/custom_operation.py @@ -35,8 +35,8 @@ def bell(): # CHECK: quake.custom_op @__nvqpp__mlirgen__custom_x_generator_1.rodata {{\[}}%[[VAL_1]]] %[[VAL_2]] : (!quake.ref, !quake.ref) -> () # CHECK: return # CHECK: } -# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__custom_h_generator_1.rodata(dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> -# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__custom_x_generator_1.rodata(dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK: cc.global constant private @__nvqpp__mlirgen__custom_h_generator_1.rodata (dense<[(0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (0.70710678118654746,0.000000e+00), (-0.70710678118654746,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK: cc.global constant private @__nvqpp__mlirgen__custom_x_generator_1.rodata (dense<[(0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> def test_custom_adjoint(): @@ -64,5 +64,5 @@ def kernel(): # CHECK: quake.h %[[VAL_0]] : (!quake.ref) -> () # CHECK: return # CHECK: } -# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__custom_s_generator_1.rodata(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> -# CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK: cc.global constant private @__nvqpp__mlirgen__custom_s_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +# CHECK: cc.global constant private @__nvqpp__mlirgen__custom_s_adj_generator_1.rodata (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (-0.000000e+00,-1.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4 diff --git a/test/AST-Quake/custom_op_concrete_matrix.cpp b/test/AST-Quake/custom_op_concrete_matrix.cpp index 0579faa996..af42818b6f 100644 --- a/test/AST-Quake/custom_op_concrete_matrix.cpp +++ b/test/AST-Quake/custom_op_concrete_matrix.cpp @@ -33,5 +33,5 @@ __qpu__ void kernel_1() { // CHECK: return // CHECK: } -// CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}}(dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> -// CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__function_custom_cnot_generator_2._Z23custom_cnot_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}}(dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<16xcomplex>) : !cc.array x 16> +// CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__function_custom_h_generator_1._Z20custom_h_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}} (dense<[(0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (0.70710678118654757,0.000000e+00), (-0.70710678118654757,0.000000e+00)]> : tensor<4xcomplex>) : !cc.array x 4> +// CHECK-DAG: cc.global constant private @__nvqpp__mlirgen__function_custom_cnot_generator_2._Z23custom_cnot_generator_{{.*}}vectorId{{.*}}.rodata_{{[0-9]+}} (dense<[(1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00), (1.000000e+00,0.000000e+00), (0.000000e+00,0.000000e+00)]> : tensor<16xcomplex>) : !cc.array x 16> diff --git a/test/AST-Quake/initialization_list.cpp b/test/AST-Quake/initialization_list.cpp index 44285eb88e..8984f3accd 100644 --- a/test/AST-Quake/initialization_list.cpp +++ b/test/AST-Quake/initialization_list.cpp @@ -44,5 +44,5 @@ __qpu__ void g() { // CHECK: return // CHECK: } -// CHECK: cc.global constant private @__nvqpp__rodata_init_0(dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00]> : tensor<4xf64>) : !cc.array +// CHECK: cc.global constant private @__nvqpp__rodata_init_0 (dense<[1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00]> : tensor<4xf64>) : !cc.array From c1b4730a1672d792b996524bf909a5578510b311 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 15 Nov 2024 15:40:32 -0800 Subject: [PATCH 07/47] Fix failing tests Signed-off-by: Anna Gringauze --- python/cudaq/kernel/captured_data.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/python/cudaq/kernel/captured_data.py b/python/cudaq/kernel/captured_data.py index d9dd033b2a..d68eb25f61 100644 --- a/python/cudaq/kernel/captured_data.py +++ b/python/cudaq/kernel/captured_data.py @@ -82,7 +82,10 @@ def storeCudaqState(self, value: cudaq_runtime.State): globalName = f'nvqpp.cudaq.state.{stateID}' setStateName = f'nvqpp.set.cudaq.state.{stateID}' with InsertionPoint.at_block_begin(self.module.body): - cc.GlobalOp(TypeAttr.get(globalTy), globalName, external=True) + cc.GlobalOp(TypeAttr.get(globalTy), + globalName, + sym_visibility=StringAttr.get("private"), + external=True) setStateFunc = func.FuncOp(setStateName, FunctionType.get(inputs=[statePtrTy], results=[]), @@ -133,7 +136,10 @@ def storeArray(self, array: np.ndarray): globalName = f'nvqpp.state.{arrayId}' setStateName = f'nvqpp.set.state.{arrayId}' with InsertionPoint.at_block_begin(self.module.body): - cc.GlobalOp(TypeAttr.get(globalTy), globalName, external=True) + cc.GlobalOp(TypeAttr.get(globalTy), + globalName, + sym_visibility=StringAttr.get("private"), + external=True) setStateFunc = func.FuncOp(setStateName, FunctionType.get(inputs=[ptrComplex], results=[]), From ec4edf73e327339b48b36ee7e2bc1ebb94460751 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Wed, 20 Nov 2024 16:53:43 -0800 Subject: [PATCH 08/47] * Added Python tests for the 'braket' target Signed-off-by: Pradnya Khalate --- .../cudaq/platform/py_alt_launch_kernel.cpp | 3 +- python/tests/backends/test_braket.py | 105 ++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 python/tests/backends/test_braket.py diff --git a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp index 6d9f9209a4..a83f95d7b2 100644 --- a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp +++ b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp @@ -557,7 +557,8 @@ MlirModule synthesizeKernel(const std::string &name, MlirModule module, pm.addPass(cudaq::opt::createStatePreparation()); } pm.addNestedPass(createCanonicalizerPass()); - pm.addNestedPass(cudaq::opt::createExpandMeasurementsPass()); + /// FIXME: Experimental change to see effect on Braket test(s) + // pm.addNestedPass(cudaq::opt::createExpandMeasurementsPass()); pm.addNestedPass(cudaq::opt::createClassicalMemToReg()); pm.addNestedPass(createCanonicalizerPass()); pm.addNestedPass(cudaq::opt::createLoopNormalize()); diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py new file mode 100644 index 0000000000..c88e31713e --- /dev/null +++ b/python/tests/backends/test_braket.py @@ -0,0 +1,105 @@ +# ============================================================================ # +# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. # +# All rights reserved. # +# # +# This source code and the accompanying materials are made available under # +# the terms of the Apache License 2.0 which accompanies this distribution. # +# ============================================================================ # + +import cudaq, pytest, os +import numpy as np +from multiprocessing import Process +from network_utils import check_server_connection + +## NOTE: Comment the following line which skips these tests in order to run in +# local dev environment after setting AWS credentials. +## NOTE: Amazon Braket costs apply +pytestmark = pytest.mark.skip("Braket credentials required") + +try: + from utils.mock_qpu.braket import startServer +except: + print("Mock qpu not available, skipping Braket tests.") + pytest.skip("Mock qpu not available.", allow_module_level=True) + +# Define the port for the mock server +port = 62445 + + +@pytest.fixture(scope="session", autouse=True) +def startUpMockServer(): + # NOTE: Credentials can be set with AWS CLI + device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" + cudaq.set_target("braket", machine=device_arn) + # Launch the Mock Server + p = Process(target=startServer, args=(port,)) + p.start() + if not check_server_connection(port): + p.terminate() + pytest.exit("Mock server did not start in time, skipping tests.", + returncode=1) + yield "Running the tests." + # Kill the server, remove the file + p.terminate() + + +def test_simple_kernel(): + + @cudaq.kernel + def kernel(): + q = cudaq.qubit() + x(q) + mz(q) + + counts = cudaq.sample(kernel, shots_count=100) + counts.dump() + + assert len(counts) == 1 + assert "1" in counts + + +def test_multi_qubit_kernel(): + + @cudaq.kernel + def kernel(): + q0 = cudaq.qubit() + q1 = cudaq.qubit() + h(q0) + cx(q0, q1) + mz(q0) + mz(q1) + + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "cannot declare a qubit register. Only 1 qubit register(s) is/are supported" in repr( + e) + + +def test_qvector_kernel(): + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + h(qubits[0]) + cx(qubits[0], qubits[1]) + mz(qubits) + + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "Could not successfully translate to qasm2" in repr(e) + + +def test_builder_sample(): + + kernel = cudaq.make_kernel() + qubits = kernel.qalloc(2) + kernel.h(qubits[0]) + kernel.cx(qubits[0], qubits[1]) + ## Fix for 'RuntimeError: At least one of the used qubits in the program need to be measured' + kernel.mz(qubits[0]) + ## Fix for 'RuntimeError: Device requires all qubits in the program to be measured. This may be caused by declaring non-contiguous qubits or measuring partial qubits' + kernel.mz(qubits[1]) + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( + e) From 6c28a93c9d334a9108c251079819879760fa23c8 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 08:36:22 -0800 Subject: [PATCH 09/47] * Skip expand measurements pass * Two more tests working Signed-off-by: Pradnya Khalate --- .../cudaq/platform/py_alt_launch_kernel.cpp | 3 +-- python/runtime/utils/PyRemoteRESTQPU.cpp | 3 ++- python/tests/backends/test_braket.py | 20 +++++++++---------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp index a83f95d7b2..6d9f9209a4 100644 --- a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp +++ b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp @@ -557,8 +557,7 @@ MlirModule synthesizeKernel(const std::string &name, MlirModule module, pm.addPass(cudaq::opt::createStatePreparation()); } pm.addNestedPass(createCanonicalizerPass()); - /// FIXME: Experimental change to see effect on Braket test(s) - // pm.addNestedPass(cudaq::opt::createExpandMeasurementsPass()); + pm.addNestedPass(cudaq::opt::createExpandMeasurementsPass()); pm.addNestedPass(cudaq::opt::createClassicalMemToReg()); pm.addNestedPass(createCanonicalizerPass()); pm.addNestedPass(cudaq::opt::createLoopNormalize()); diff --git a/python/runtime/utils/PyRemoteRESTQPU.cpp b/python/runtime/utils/PyRemoteRESTQPU.cpp index aa79808c37..658e42a5d7 100644 --- a/python/runtime/utils/PyRemoteRESTQPU.cpp +++ b/python/runtime/utils/PyRemoteRESTQPU.cpp @@ -89,7 +89,8 @@ class PyRemoteRESTQPU : public cudaq::BaseRemoteRESTQPU { pm.addPass(mlir::createCanonicalizerPass()); pm.addPass(cudaq::opt::createApplyOpSpecializationPass()); pm.addPass(createInlinerPass()); - pm.addPass(cudaq::opt::createExpandMeasurementsPass()); + /// FIXME: Experimental change to see effect on Braket test(s) + // pm.addPass(cudaq::opt::createExpandMeasurementsPass()); pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); if (failed(pm.run(cloned))) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index c88e31713e..a28a2b0373 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -84,9 +84,10 @@ def kernel(): cx(qubits[0], qubits[1]) mz(qubits) - with pytest.raises(RuntimeError) as e: - cudaq.sample(kernel, shots_count=100) - assert "Could not successfully translate to qasm2" in repr(e) + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 2 + assert "00" in counts + assert "11" in counts def test_builder_sample(): @@ -95,11 +96,8 @@ def test_builder_sample(): qubits = kernel.qalloc(2) kernel.h(qubits[0]) kernel.cx(qubits[0], qubits[1]) - ## Fix for 'RuntimeError: At least one of the used qubits in the program need to be measured' - kernel.mz(qubits[0]) - ## Fix for 'RuntimeError: Device requires all qubits in the program to be measured. This may be caused by declaring non-contiguous qubits or measuring partial qubits' - kernel.mz(qubits[1]) - with pytest.raises(RuntimeError) as e: - cudaq.sample(kernel, shots_count=100) - assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( - e) + kernel.mz(qubits) + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 2 + assert "00" in counts + assert "11" in counts From c68ba3edd0ead64098f19daece286904e07d5e48 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 10:37:22 -0800 Subject: [PATCH 10/47] * Ignore classical operations in OpenQASM2.0 translation * Additional tests Co-authored-by: Eric Schweitz Signed-off-by: Pradnya Khalate --- lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp | 6 +++ python/runtime/utils/PyRemoteRESTQPU.cpp | 3 +- python/tests/backends/test_braket.py | 47 ++++++++++++++++++- .../default/rest/helpers/braket/braket.yml | 2 +- 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp index 26e355b472..04c431b0ab 100644 --- a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp +++ b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp @@ -9,6 +9,7 @@ #include "cudaq/Frontend/nvqpp/AttributeNames.h" #include "cudaq/Optimizer/CodeGen/Emitter.h" #include "cudaq/Optimizer/CodeGen/OpenQASMEmitter.h" +#include "cudaq/Optimizer/Dialect/CC/CCOps.h" #include "cudaq/Optimizer/Dialect/CC/CCTypes.h" #include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h" #include "llvm/ADT/PostOrderIterator.h" @@ -345,6 +346,11 @@ static LogicalResult emitOperation(Emitter &emitter, Operation &op) { .Case([&](auto op) { return success(); }) .Case([&](auto op) { return success(); }) .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) .Default([&](Operation *) -> LogicalResult { if (op.getName().getDialectNamespace().equals("llvm")) return success(); diff --git a/python/runtime/utils/PyRemoteRESTQPU.cpp b/python/runtime/utils/PyRemoteRESTQPU.cpp index 658e42a5d7..58dca879df 100644 --- a/python/runtime/utils/PyRemoteRESTQPU.cpp +++ b/python/runtime/utils/PyRemoteRESTQPU.cpp @@ -89,7 +89,8 @@ class PyRemoteRESTQPU : public cudaq::BaseRemoteRESTQPU { pm.addPass(mlir::createCanonicalizerPass()); pm.addPass(cudaq::opt::createApplyOpSpecializationPass()); pm.addPass(createInlinerPass()); - /// FIXME: Experimental change to see effect on Braket test(s) + /// NOTE: This change is for the `braket` target. May require additional + /// pass in other pipelines. // pm.addPass(cudaq::opt::createExpandMeasurementsPass()); pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index a28a2b0373..62655e23d3 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -71,7 +71,7 @@ def kernel(): with pytest.raises(RuntimeError) as e: cudaq.sample(kernel, shots_count=100) - assert "cannot declare a qubit register. Only 1 qubit register(s) is/are supported" in repr( + assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( e) @@ -101,3 +101,48 @@ def test_builder_sample(): assert len(counts) == 2 assert "00" in counts assert "11" in counts + + +def test_control_modifier(): + + @cudaq.kernel + def bell(): + qubits = cudaq.qvector(2) + h(qubits[0]) + x.ctrl(qubits[0], qubits[1]) + mz(qubits) + + counts = cudaq.sample(bell, shots_count=100) + assert len(counts) == 2 + assert "00" in counts + assert "11" in counts + + +def test_adjoint_modifier(): + + @cudaq.kernel + def single_adjoint_test(): + q = cudaq.qubit() + s(q) + s.adj(q) + mz(q) + + with pytest.raises(RuntimeError) as e: + counts = cudaq.sample(single_adjoint_test, shots_count=100) + assert "uses a gate: sdg which is not supported by the device or defined via a defcal" in repr( + e) + + @cudaq.kernel + def rotation_adjoint_test(): + q = cudaq.qubit() + rx(1.1, q) + rx.adj(1.1, q) + + ry(1.1, q) + ry.adj(1.1, q) + + mz(q) + + counts = cudaq.sample(rotation_adjoint_test, shots_count=100) + assert '0' in counts + assert len(counts) == 1 diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 0ca82c4736..93ce0596e2 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition,combine-quantum-alloc,canonicalize),decomposition{enable-patterns=CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From 43a6cdacd970ffe9cb988bb6ea9a1c41ac212388 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 11:36:51 -0800 Subject: [PATCH 11/47] * Support U3 gate Signed-off-by: Pradnya Khalate --- python/tests/backends/test_braket.py | 27 ++++++++++++++++++- .../default/rest/helpers/braket/braket.yml | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 62655e23d3..457a193ffe 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -128,7 +128,7 @@ def single_adjoint_test(): mz(q) with pytest.raises(RuntimeError) as e: - counts = cudaq.sample(single_adjoint_test, shots_count=100) + cudaq.sample(single_adjoint_test, shots_count=100) assert "uses a gate: sdg which is not supported by the device or defined via a defcal" in repr( e) @@ -146,3 +146,28 @@ def rotation_adjoint_test(): counts = cudaq.sample(rotation_adjoint_test, shots_count=100) assert '0' in counts assert len(counts) == 1 + + +def test_u3_decomposition(): + + @cudaq.kernel + def kernel(): + qubit = cudaq.qubit() + u3(0.0, np.pi / 2, np.pi, qubit) + mz(qubit) + + # Test here is that this runs + result = cudaq.sample(kernel, shots_count=100) + measurement_probabilities = dict(result.items()) + print(measurement_probabilities) + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + u3.ctrl(0.0, np.pi / 2, np.pi, qubits[0], qubits[1]) + mz(qubits) + + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "uses a gate: crz which is not supported by the device or defined via a defcal" in repr( + e) diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 93ce0596e2..ed21941c8c 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition,combine-quantum-alloc,canonicalize),decomposition{enable-patterns=CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition,combine-quantum-alloc,canonicalize),decomposition{enable-patterns=U3ToRotations,CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From cfe5c125a355a8c1d48c6a80475b605e040d8877 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 11:49:32 -0800 Subject: [PATCH 12/47] * Test for other simulators * Test for asynchronous sampling API * Failing test for observe API * More tests to cover all native gates, custom operations * One more test - check kernel that takes arguments Signed-off-by: Pradnya Khalate --- python/tests/backends/test_braket.py | 131 ++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 1 deletion(-) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 457a193ffe..546c3d195b 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -6,7 +6,10 @@ # the terms of the Apache License 2.0 which accompanies this distribution. # # ============================================================================ # -import cudaq, pytest, os +import cudaq +import pytest +import os +from cudaq import spin import numpy as np from multiprocessing import Process from network_utils import check_server_connection @@ -103,6 +106,40 @@ def test_builder_sample(): assert "11" in counts +def test_all_gates(): + + @cudaq.kernel + def single_qubit_gates(): + q = cudaq.qubit() + h(q) + x(q) + y(q) + z(q) + # r1(np.pi, q) ## Unsupported + rx(np.pi, q) + ry(np.pi, q) + rz(np.pi, q) + s(q) + t(q) + # mx(q) ## Unsupported + # my(q) ## Unsupported + mz(q) + + # Test here is that this runs + cudaq.sample(single_qubit_gates, shots_count=100).dump() + + @cudaq.kernel + def two_qubit_gates(): + qubits = cudaq.qvector(2) + x(qubits[0]) + swap(qubits[0], qubits[1]) + mz(qubits) + + counts = cudaq.sample(two_qubit_gates, shots_count=100) + assert len(counts) == 1 + assert "01" in counts + + def test_control_modifier(): @cudaq.kernel @@ -171,3 +208,95 @@ def kernel(): cudaq.sample(kernel, shots_count=100) assert "uses a gate: crz which is not supported by the device or defined via a defcal" in repr( e) + + +def test_sample_async(): + cudaq.set_random_seed(13) + + @cudaq.kernel + def simple(): + qubits = cudaq.qvector(2) + h(qubits[0]) + x.ctrl(qubits[0], qubits[1]) + mz(qubits) + + future = cudaq.sample_async(simple) + counts = future.get() + assert (len(counts) == 2) + assert ('00' in counts) + assert ('11' in counts) + + +def test_observe(): + cudaq.set_random_seed(13) + + @cudaq.kernel + def ansatz(theta: float): + qreg = cudaq.qvector(2) + x(qreg[0]) + ry(theta, qreg[1]) + x.ctrl(qreg[1], qreg[0]) + ## NOTE: Measure required since 'Device requires all qubits in the program to be measured.' + mz(qreg) + + # Define its spin Hamiltonian. + hamiltonian = 5.907 - 2.1433 * spin.x(0) * spin.x(1) - 2.1433 * spin.y( + 0) * spin.y(1) + .21829 * spin.z(0) - 6.125 * spin.z(1) + + with pytest.raises(RuntimeError) as e: + cudaq.observe(ansatz, hamiltonian, .59, shots_count=100) + assert "observe specification violated for 'ansatz': kernels passed to observe cannot have measurements specified." in repr( + e) + + +def test_custom_operations(): + + cudaq.register_operation("custom_x", np.array([0, 1, 1, 0])) + + @cudaq.kernel + def basic_x(): + qubit = cudaq.qubit() + custom_x(qubit) + + ## NOTE: `translateOperatorName` function in `lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp` + # replaces `r1` with `u1` + with pytest.raises(RuntimeError) as e: + cudaq.sample(basic_x, shots_count=100) + assert "uses a gate: u1 which is not supported by the device or defined via a defcal" in repr( + e) + + +def test_kernel_with_args(): + + @cudaq.kernel + def kernel(qubit_count: int): + qreg = cudaq.qvector(qubit_count) + h(qreg[0]) + for qubit in range(qubit_count - 1): + x.ctrl(qreg[qubit], qreg[qubit + 1]) + mz(qreg) + + counts = cudaq.sample(kernel, 8, shots_count=100) + assert len(counts) == 2 + assert "00000000" in counts + assert "11111111" in counts + + +@pytest.mark.parametrize("device_arn", [ + "arn:aws:braket:::device/quantum-simulator/amazon/dm1", + "arn:aws:braket:::device/quantum-simulator/amazon/tn1" +]) +def test_other_simulators(device_arn): + + cudaq.set_target("braket", machine=device_arn) + + test_qvector_kernel() + test_builder_sample() + + cudaq.reset_target() + + +# leave for gdb debugging +if __name__ == "__main__": + loc = os.path.abspath(__file__) + pytest.main([loc, "-s"]) From ed228bfbd96ef09d0ee2de4c152487c1bc9915b6 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 14:47:02 -0800 Subject: [PATCH 13/47] * Remove the `combine-quantum-alloc` pass since multiple registers are not supported. * Simplify test setup since mock server isn't being used. Signed-off-by: Pradnya Khalate --- python/tests/backends/test_braket.py | 46 ++++++++----------- .../default/rest/helpers/braket/braket.yml | 2 +- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 546c3d195b..2b8271fca0 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -19,31 +19,14 @@ ## NOTE: Amazon Braket costs apply pytestmark = pytest.mark.skip("Braket credentials required") -try: - from utils.mock_qpu.braket import startServer -except: - print("Mock qpu not available, skipping Braket tests.") - pytest.skip("Mock qpu not available.", allow_module_level=True) - -# Define the port for the mock server -port = 62445 - @pytest.fixture(scope="session", autouse=True) -def startUpMockServer(): - # NOTE: Credentials can be set with AWS CLI +def do_something(): device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" cudaq.set_target("braket", machine=device_arn) - # Launch the Mock Server - p = Process(target=startServer, args=(port,)) - p.start() - if not check_server_connection(port): - p.terminate() - pytest.exit("Mock server did not start in time, skipping tests.", - returncode=1) yield "Running the tests." - # Kill the server, remove the file - p.terminate() + cudaq.__clearKernelRegistries() + cudaq.reset_target() def test_simple_kernel(): @@ -74,7 +57,7 @@ def kernel(): with pytest.raises(RuntimeError) as e: cudaq.sample(kernel, shots_count=100) - assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( + assert "cannot declare a qubit register. Only 1 qubit register(s) is/are supported" in repr( e) @@ -140,6 +123,22 @@ def two_qubit_gates(): assert "01" in counts +def test_multi_qvector(): + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + ancilla = cudaq.qvector(2) + x(qubits) + h(ancilla) + mz(ancilla) + + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "cannot declare a qubit register. Only 1 qubit register(s) is/are supported" in repr( + e) + + def test_control_modifier(): @cudaq.kernel @@ -174,10 +173,8 @@ def rotation_adjoint_test(): q = cudaq.qubit() rx(1.1, q) rx.adj(1.1, q) - ry(1.1, q) ry.adj(1.1, q) - mz(q) counts = cudaq.sample(rotation_adjoint_test, shots_count=100) @@ -287,12 +284,9 @@ def kernel(qubit_count: int): "arn:aws:braket:::device/quantum-simulator/amazon/tn1" ]) def test_other_simulators(device_arn): - cudaq.set_target("braket", machine=device_arn) - test_qvector_kernel() test_builder_sample() - cudaq.reset_target() diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index ed21941c8c..44903e032f 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition,combine-quantum-alloc,canonicalize),decomposition{enable-patterns=U3ToRotations,CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=U3ToRotations,CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From 35138a0af1092b608260792f4f9bba4433989481 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 15:47:49 -0800 Subject: [PATCH 14/47] * Clean-up test, use 'Amazon Braket' in messages Signed-off-by: Pradnya Khalate --- python/tests/backends/test_QuEra.py | 2 +- python/tests/backends/test_braket.py | 12 ++++-------- .../rest/helpers/braket/BraketServerHelper.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/python/tests/backends/test_QuEra.py b/python/tests/backends/test_QuEra.py index 97492ffb9e..8f8c56012b 100644 --- a/python/tests/backends/test_QuEra.py +++ b/python/tests/backends/test_QuEra.py @@ -42,7 +42,7 @@ def startUpMockServer(): p.terminate() -@pytest.mark.skip(reason="Braket credentials required") +@pytest.mark.skip(reason="Amazon Braket credentials required") def test_JSON_payload(): input = { "braketSchemaHeader": { diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 2b8271fca0..551dcb3fc7 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -11,13 +11,11 @@ import os from cudaq import spin import numpy as np -from multiprocessing import Process -from network_utils import check_server_connection ## NOTE: Comment the following line which skips these tests in order to run in # local dev environment after setting AWS credentials. ## NOTE: Amazon Braket costs apply -pytestmark = pytest.mark.skip("Braket credentials required") +pytestmark = pytest.mark.skip("Amazon Braket credentials required") @pytest.fixture(scope="session", autouse=True) @@ -38,8 +36,6 @@ def kernel(): mz(q) counts = cudaq.sample(kernel, shots_count=100) - counts.dump() - assert len(counts) == 1 assert "1" in counts @@ -273,10 +269,10 @@ def kernel(qubit_count: int): x.ctrl(qreg[qubit], qreg[qubit + 1]) mz(qreg) - counts = cudaq.sample(kernel, 8, shots_count=100) + counts = cudaq.sample(kernel, 4, shots_count=100) assert len(counts) == 2 - assert "00000000" in counts - assert "11111111" in counts + assert "0000" in counts + assert "1111" in counts @pytest.mark.parametrize("device_arn", [ diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp index 76cfb680e6..26ba0ceb42 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp @@ -34,8 +34,8 @@ std::string getDeviceArn(const std::string &machine) { for (const auto &machine : deviceArns) knownMachines += machine.first + " "; const auto errorMessage = - fmt::format("Machine \"{}\" is invalid. Machine must be either a Braket " - "device ARN or one of the known devices: {}", + fmt::format("Machine \"{}\" is invalid. Machine must be either an Amazon " + "Braket device ARN or one of the known devices: {}", machine, knownMachines); throw std::runtime_error(errorMessage); } @@ -68,8 +68,8 @@ void BraketServerHelper::initialize(BackendConfig config) { const auto emulate_it = config.find("emulate"); if (emulate_it != config.end() && emulate_it->second == "true") { - cudaq::info("Emulation is enabled, ignore all Braket connection specific " - "information."); + cudaq::info("Emulation is enabled, ignore all Amazon Braket connection " + "specific information."); backendConfig = std::move(config); return; } From bcf905404217a4d48c2741028382d21535b87889 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Fri, 22 Nov 2024 12:00:45 -0800 Subject: [PATCH 15/47] * Decomposition patterns for R1, CRz, Sdg Co-authored-by: Bettina Heim Signed-off-by: Pradnya Khalate --- lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp | 4 +- .../Transforms/DecompositionPatterns.cpp | 49 +++++++++++++++++++ python/tests/backends/test_braket.py | 16 +++--- .../default/rest/helpers/braket/braket.yml | 2 +- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp index 04c431b0ab..e567f53d1e 100644 --- a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp +++ b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp @@ -23,13 +23,13 @@ using namespace cudaq; //===----------------------------------------------------------------------===// // Helper functions //===----------------------------------------------------------------------===// - +/// FIXME: Remove this code /// Translates operation names into OpenQASM gate names static LogicalResult translateOperatorName(quake::OperatorInterface optor, StringRef &name) { StringRef qkeName = optor->getName().stripDialect(); if (optor.getControls().size() == 0) { - name = StringSwitch(qkeName).Case("r1", "u1").Default(qkeName); + name = StringSwitch(qkeName).Default(qkeName); } else if (optor.getControls().size() == 1) { name = StringSwitch(qkeName) .Case("h", "ch") diff --git a/lib/Optimizer/Transforms/DecompositionPatterns.cpp b/lib/Optimizer/Transforms/DecompositionPatterns.cpp index bdf8e9244c..d1cfdb13ba 100644 --- a/lib/Optimizer/Transforms/DecompositionPatterns.cpp +++ b/lib/Optimizer/Transforms/DecompositionPatterns.cpp @@ -460,6 +460,25 @@ struct R1ToRz : public OpRewritePattern { } }; +// Naive mapping of R1 to U3, ignoring the global phase. +// This is only expected to work with full inlining and +// quake apply specialization. +struct R1ToU3 : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + void initialize() { setDebugName("R1ToU3"); } + + LogicalResult matchAndRewrite(quake::R1Op r1Op, + PatternRewriter &rewriter) const override { + Location loc = r1Op->getLoc(); + Value zero = createConstant(loc, 0.0, rewriter.getF64Type(), rewriter); + std::array parameters = {zero, zero, r1Op.getParameters()[0]}; + rewriter.replaceOpWithNewOp( + r1Op, r1Op.isAdj(), parameters, r1Op.getControls(), r1Op.getTargets()); + return success(); + } +}; + // quake.swap a, b // ─────────────────────────────────── // quake.cnot b, a; @@ -603,6 +622,34 @@ struct SToR1 : public OpRewritePattern { } }; +// quake.s target +// ───────────────────────────────── +// (quake.z * quake.s) target +struct SAdjToSZ : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + void initialize() { setDebugName("SAdjToSZ"); } + + LogicalResult matchAndRewrite(quake::SOp op, + PatternRewriter &rewriter) const override { + if (!op.isAdj()) + return failure(); + + // Op info + auto loc = op->getLoc(); + auto parameters = op.getParameters(); + SmallVector controls(op.getControls()); + Value target = op.getTarget(); + + QuakeOperatorCreator qRewriter(rewriter); + qRewriter.create(loc, parameters, controls, target); + qRewriter.create(loc, parameters, controls, target); + qRewriter.selectWiresAndReplaceUses(op, controls, target); + rewriter.eraseOp(op); + return success(); + } +}; + //===----------------------------------------------------------------------===// // TOp decompositions //===----------------------------------------------------------------------===// @@ -1537,6 +1584,7 @@ void cudaq::populateWithAllDecompositionPatterns(RewritePatternSet &patterns) { // SOp patterns SToPhasedRx, SToR1, + SAdjToSZ, // TOp patterns TToPhasedRx, TToR1, @@ -1554,6 +1602,7 @@ void cudaq::populateWithAllDecompositionPatterns(RewritePatternSet &patterns) { CR1ToCX, R1ToPhasedRx, R1ToRz, + R1ToU3, // RxOp patterns CRxToCX, RxToPhasedRx, diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 551dcb3fc7..5fd216c5b1 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -94,7 +94,7 @@ def single_qubit_gates(): x(q) y(q) z(q) - # r1(np.pi, q) ## Unsupported + r1(np.pi, q) rx(np.pi, q) ry(np.pi, q) rz(np.pi, q) @@ -159,10 +159,9 @@ def single_adjoint_test(): s.adj(q) mz(q) - with pytest.raises(RuntimeError) as e: - cudaq.sample(single_adjoint_test, shots_count=100) - assert "uses a gate: sdg which is not supported by the device or defined via a defcal" in repr( - e) + counts = cudaq.sample(single_adjoint_test, shots_count=100) + assert len(counts) == 1 + assert "0" in counts @cudaq.kernel def rotation_adjoint_test(): @@ -197,10 +196,9 @@ def kernel(): u3.ctrl(0.0, np.pi / 2, np.pi, qubits[0], qubits[1]) mz(qubits) - with pytest.raises(RuntimeError) as e: - cudaq.sample(kernel, shots_count=100) - assert "uses a gate: crz which is not supported by the device or defined via a defcal" in repr( - e) + counts = cudaq.sample(kernel, shots_count=100) + assert '00' in counts + assert len(counts) == 1 def test_sample_async(): diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 44903e032f..09ee016649 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=U3ToRotations,CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From 2047b2b6bc22cf29742844f2435d0062afc8782f Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 22 Nov 2024 13:52:44 -0800 Subject: [PATCH 16/47] Remove and add some passes to braket Signed-off-by: Anna Gringauze --- lib/Optimizer/CodeGen/Pipelines.cpp | 4 +++- python/cudaq/kernel/ast_bridge.py | 1 + .../runtime/cudaq/platform/py_alt_launch_kernel.cpp | 11 ++++++++++- python/runtime/utils/PyRemoteRESTQPU.cpp | 2 +- .../platform/default/rest/helpers/braket/braket.yml | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/Optimizer/CodeGen/Pipelines.cpp b/lib/Optimizer/CodeGen/Pipelines.cpp index 23e7c83f5f..662061dc7a 100644 --- a/lib/Optimizer/CodeGen/Pipelines.cpp +++ b/lib/Optimizer/CodeGen/Pipelines.cpp @@ -58,7 +58,9 @@ void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) { pm.addNestedPass(createMultiControlDecompositionPass()); pm.addPass(createDecompositionPass( {.enabledPatterns = {"CCZToCX", "RxAdjToRx", "RyAdjToRy", "RzAdjToRz"}})); - pm.addPass(createCanonicalizerPass()); + pm.addNestedPass(createExpandControlVeqs()); + pm.addNestedPass(createCombineQuantumAllocations()); + pm.addNestedPass(createCanonicalizerPass()); } void cudaq::opt::addPipelineTranslateToIQMJson(PassManager &pm) { diff --git a/python/cudaq/kernel/ast_bridge.py b/python/cudaq/kernel/ast_bridge.py index cae278143f..8803ccf011 100644 --- a/python/cudaq/kernel/ast_bridge.py +++ b/python/cudaq/kernel/ast_bridge.py @@ -4032,4 +4032,5 @@ def compile_to_mlir(astModule, metadata, if len(bridge.dependentCaptureVars): extraMetaData['dependent_captures'] = bridge.dependentCaptureVars + bridge.module.dump() return bridge.module, bridge.argTypes, extraMetaData diff --git a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp index 6d9f9209a4..3bdf17f860 100644 --- a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp +++ b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp @@ -561,7 +561,7 @@ MlirModule synthesizeKernel(const std::string &name, MlirModule module, pm.addNestedPass(cudaq::opt::createClassicalMemToReg()); pm.addNestedPass(createCanonicalizerPass()); pm.addNestedPass(cudaq::opt::createLoopNormalize()); - pm.addNestedPass(cudaq::opt::createLoopUnroll()); + pm.addPass(cudaq::opt::createLoopUnroll()); pm.addNestedPass(createCanonicalizerPass()); DefaultTimingManager tm; tm.setEnabled(cudaq::isTimingTagEnabled(cudaq::TIMING_JIT_PASSES)); @@ -633,10 +633,19 @@ std::string getASM(const std::string &name, MlirModule module, auto cloned = unwrap(module).clone(); auto context = cloned.getContext(); + // Get additional debug values + auto disableMLIRthreading = getEnvBool("CUDAQ_MLIR_DISABLE_THREADING", false); + auto enablePrintMLIREachPass = + getEnvBool("CUDAQ_MLIR_PRINT_EACH_PASS", false); + PassManager pm(context); pm.addPass(cudaq::opt::createLambdaLiftingPass()); cudaq::opt::addPipelineTranslateToOpenQASM(pm); + if (disableMLIRthreading || enablePrintMLIREachPass) + context->disableMultithreading(); + if (enablePrintMLIREachPass) + pm.enableIRPrinting(); if (failed(pm.run(cloned))) throw std::runtime_error("getASM: code generation failed."); std::free(rawArgs); diff --git a/python/runtime/utils/PyRemoteRESTQPU.cpp b/python/runtime/utils/PyRemoteRESTQPU.cpp index aa79808c37..bbfeb2ca04 100644 --- a/python/runtime/utils/PyRemoteRESTQPU.cpp +++ b/python/runtime/utils/PyRemoteRESTQPU.cpp @@ -89,7 +89,7 @@ class PyRemoteRESTQPU : public cudaq::BaseRemoteRESTQPU { pm.addPass(mlir::createCanonicalizerPass()); pm.addPass(cudaq::opt::createApplyOpSpecializationPass()); pm.addPass(createInlinerPass()); - pm.addPass(cudaq::opt::createExpandMeasurementsPass()); + //pm.addPass(cudaq::opt::createExpandMeasurementsPass()); pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); if (failed(pm.run(cloned))) diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 0ca82c4736..a54dd38aaa 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0},expand-control-veqs,canonicalize,combine-quantum-alloc),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From 48a3de3555d414ad204d8c79f467ac12fb40aa4e Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Wed, 20 Nov 2024 16:53:43 -0800 Subject: [PATCH 17/47] * Added Python tests for the 'braket' target Signed-off-by: Pradnya Khalate --- .../cudaq/platform/py_alt_launch_kernel.cpp | 3 +- python/tests/backends/test_braket.py | 105 ++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 python/tests/backends/test_braket.py diff --git a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp index ead6ba5129..224e65d8ec 100644 --- a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp +++ b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp @@ -558,7 +558,8 @@ MlirModule synthesizeKernel(const std::string &name, MlirModule module, pm.addPass(cudaq::opt::createStatePreparation()); } pm.addNestedPass(createCanonicalizerPass()); - pm.addNestedPass(cudaq::opt::createExpandMeasurementsPass()); + /// FIXME: Experimental change to see effect on Braket test(s) + // pm.addNestedPass(cudaq::opt::createExpandMeasurementsPass()); pm.addNestedPass(cudaq::opt::createClassicalMemToReg()); pm.addNestedPass(createCanonicalizerPass()); pm.addNestedPass(cudaq::opt::createLoopNormalize()); diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py new file mode 100644 index 0000000000..c88e31713e --- /dev/null +++ b/python/tests/backends/test_braket.py @@ -0,0 +1,105 @@ +# ============================================================================ # +# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. # +# All rights reserved. # +# # +# This source code and the accompanying materials are made available under # +# the terms of the Apache License 2.0 which accompanies this distribution. # +# ============================================================================ # + +import cudaq, pytest, os +import numpy as np +from multiprocessing import Process +from network_utils import check_server_connection + +## NOTE: Comment the following line which skips these tests in order to run in +# local dev environment after setting AWS credentials. +## NOTE: Amazon Braket costs apply +pytestmark = pytest.mark.skip("Braket credentials required") + +try: + from utils.mock_qpu.braket import startServer +except: + print("Mock qpu not available, skipping Braket tests.") + pytest.skip("Mock qpu not available.", allow_module_level=True) + +# Define the port for the mock server +port = 62445 + + +@pytest.fixture(scope="session", autouse=True) +def startUpMockServer(): + # NOTE: Credentials can be set with AWS CLI + device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" + cudaq.set_target("braket", machine=device_arn) + # Launch the Mock Server + p = Process(target=startServer, args=(port,)) + p.start() + if not check_server_connection(port): + p.terminate() + pytest.exit("Mock server did not start in time, skipping tests.", + returncode=1) + yield "Running the tests." + # Kill the server, remove the file + p.terminate() + + +def test_simple_kernel(): + + @cudaq.kernel + def kernel(): + q = cudaq.qubit() + x(q) + mz(q) + + counts = cudaq.sample(kernel, shots_count=100) + counts.dump() + + assert len(counts) == 1 + assert "1" in counts + + +def test_multi_qubit_kernel(): + + @cudaq.kernel + def kernel(): + q0 = cudaq.qubit() + q1 = cudaq.qubit() + h(q0) + cx(q0, q1) + mz(q0) + mz(q1) + + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "cannot declare a qubit register. Only 1 qubit register(s) is/are supported" in repr( + e) + + +def test_qvector_kernel(): + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + h(qubits[0]) + cx(qubits[0], qubits[1]) + mz(qubits) + + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "Could not successfully translate to qasm2" in repr(e) + + +def test_builder_sample(): + + kernel = cudaq.make_kernel() + qubits = kernel.qalloc(2) + kernel.h(qubits[0]) + kernel.cx(qubits[0], qubits[1]) + ## Fix for 'RuntimeError: At least one of the used qubits in the program need to be measured' + kernel.mz(qubits[0]) + ## Fix for 'RuntimeError: Device requires all qubits in the program to be measured. This may be caused by declaring non-contiguous qubits or measuring partial qubits' + kernel.mz(qubits[1]) + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( + e) From 76348179caa1b3bce85091dae26e7f2fcf4cc6c1 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 08:36:22 -0800 Subject: [PATCH 18/47] * Skip expand measurements pass * Two more tests working Signed-off-by: Pradnya Khalate --- .../cudaq/platform/py_alt_launch_kernel.cpp | 3 +-- python/runtime/utils/PyRemoteRESTQPU.cpp | 3 ++- python/tests/backends/test_braket.py | 20 +++++++++---------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp index 224e65d8ec..ead6ba5129 100644 --- a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp +++ b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp @@ -558,8 +558,7 @@ MlirModule synthesizeKernel(const std::string &name, MlirModule module, pm.addPass(cudaq::opt::createStatePreparation()); } pm.addNestedPass(createCanonicalizerPass()); - /// FIXME: Experimental change to see effect on Braket test(s) - // pm.addNestedPass(cudaq::opt::createExpandMeasurementsPass()); + pm.addNestedPass(cudaq::opt::createExpandMeasurementsPass()); pm.addNestedPass(cudaq::opt::createClassicalMemToReg()); pm.addNestedPass(createCanonicalizerPass()); pm.addNestedPass(cudaq::opt::createLoopNormalize()); diff --git a/python/runtime/utils/PyRemoteRESTQPU.cpp b/python/runtime/utils/PyRemoteRESTQPU.cpp index aa79808c37..658e42a5d7 100644 --- a/python/runtime/utils/PyRemoteRESTQPU.cpp +++ b/python/runtime/utils/PyRemoteRESTQPU.cpp @@ -89,7 +89,8 @@ class PyRemoteRESTQPU : public cudaq::BaseRemoteRESTQPU { pm.addPass(mlir::createCanonicalizerPass()); pm.addPass(cudaq::opt::createApplyOpSpecializationPass()); pm.addPass(createInlinerPass()); - pm.addPass(cudaq::opt::createExpandMeasurementsPass()); + /// FIXME: Experimental change to see effect on Braket test(s) + // pm.addPass(cudaq::opt::createExpandMeasurementsPass()); pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); if (failed(pm.run(cloned))) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index c88e31713e..a28a2b0373 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -84,9 +84,10 @@ def kernel(): cx(qubits[0], qubits[1]) mz(qubits) - with pytest.raises(RuntimeError) as e: - cudaq.sample(kernel, shots_count=100) - assert "Could not successfully translate to qasm2" in repr(e) + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 2 + assert "00" in counts + assert "11" in counts def test_builder_sample(): @@ -95,11 +96,8 @@ def test_builder_sample(): qubits = kernel.qalloc(2) kernel.h(qubits[0]) kernel.cx(qubits[0], qubits[1]) - ## Fix for 'RuntimeError: At least one of the used qubits in the program need to be measured' - kernel.mz(qubits[0]) - ## Fix for 'RuntimeError: Device requires all qubits in the program to be measured. This may be caused by declaring non-contiguous qubits or measuring partial qubits' - kernel.mz(qubits[1]) - with pytest.raises(RuntimeError) as e: - cudaq.sample(kernel, shots_count=100) - assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( - e) + kernel.mz(qubits) + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 2 + assert "00" in counts + assert "11" in counts From 6b2469f11c15b0f6977ba71c6e1f1c03bed54ded Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 10:37:22 -0800 Subject: [PATCH 19/47] * Ignore classical operations in OpenQASM2.0 translation * Additional tests Co-authored-by: Eric Schweitz Signed-off-by: Pradnya Khalate --- lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp | 6 +++ python/runtime/utils/PyRemoteRESTQPU.cpp | 3 +- python/tests/backends/test_braket.py | 47 ++++++++++++++++++- .../default/rest/helpers/braket/braket.yml | 2 +- 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp index 26e355b472..04c431b0ab 100644 --- a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp +++ b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp @@ -9,6 +9,7 @@ #include "cudaq/Frontend/nvqpp/AttributeNames.h" #include "cudaq/Optimizer/CodeGen/Emitter.h" #include "cudaq/Optimizer/CodeGen/OpenQASMEmitter.h" +#include "cudaq/Optimizer/Dialect/CC/CCOps.h" #include "cudaq/Optimizer/Dialect/CC/CCTypes.h" #include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h" #include "llvm/ADT/PostOrderIterator.h" @@ -345,6 +346,11 @@ static LogicalResult emitOperation(Emitter &emitter, Operation &op) { .Case([&](auto op) { return success(); }) .Case([&](auto op) { return success(); }) .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) + .Case([&](auto op) { return success(); }) .Default([&](Operation *) -> LogicalResult { if (op.getName().getDialectNamespace().equals("llvm")) return success(); diff --git a/python/runtime/utils/PyRemoteRESTQPU.cpp b/python/runtime/utils/PyRemoteRESTQPU.cpp index 658e42a5d7..58dca879df 100644 --- a/python/runtime/utils/PyRemoteRESTQPU.cpp +++ b/python/runtime/utils/PyRemoteRESTQPU.cpp @@ -89,7 +89,8 @@ class PyRemoteRESTQPU : public cudaq::BaseRemoteRESTQPU { pm.addPass(mlir::createCanonicalizerPass()); pm.addPass(cudaq::opt::createApplyOpSpecializationPass()); pm.addPass(createInlinerPass()); - /// FIXME: Experimental change to see effect on Braket test(s) + /// NOTE: This change is for the `braket` target. May require additional + /// pass in other pipelines. // pm.addPass(cudaq::opt::createExpandMeasurementsPass()); pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index a28a2b0373..62655e23d3 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -71,7 +71,7 @@ def kernel(): with pytest.raises(RuntimeError) as e: cudaq.sample(kernel, shots_count=100) - assert "cannot declare a qubit register. Only 1 qubit register(s) is/are supported" in repr( + assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( e) @@ -101,3 +101,48 @@ def test_builder_sample(): assert len(counts) == 2 assert "00" in counts assert "11" in counts + + +def test_control_modifier(): + + @cudaq.kernel + def bell(): + qubits = cudaq.qvector(2) + h(qubits[0]) + x.ctrl(qubits[0], qubits[1]) + mz(qubits) + + counts = cudaq.sample(bell, shots_count=100) + assert len(counts) == 2 + assert "00" in counts + assert "11" in counts + + +def test_adjoint_modifier(): + + @cudaq.kernel + def single_adjoint_test(): + q = cudaq.qubit() + s(q) + s.adj(q) + mz(q) + + with pytest.raises(RuntimeError) as e: + counts = cudaq.sample(single_adjoint_test, shots_count=100) + assert "uses a gate: sdg which is not supported by the device or defined via a defcal" in repr( + e) + + @cudaq.kernel + def rotation_adjoint_test(): + q = cudaq.qubit() + rx(1.1, q) + rx.adj(1.1, q) + + ry(1.1, q) + ry.adj(1.1, q) + + mz(q) + + counts = cudaq.sample(rotation_adjoint_test, shots_count=100) + assert '0' in counts + assert len(counts) == 1 diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 0ca82c4736..93ce0596e2 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition,combine-quantum-alloc,canonicalize),decomposition{enable-patterns=CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From 45205be6a457e4038d2d083ba9df161b659f8007 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 11:36:51 -0800 Subject: [PATCH 20/47] * Support U3 gate Signed-off-by: Pradnya Khalate --- python/tests/backends/test_braket.py | 27 ++++++++++++++++++- .../default/rest/helpers/braket/braket.yml | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 62655e23d3..457a193ffe 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -128,7 +128,7 @@ def single_adjoint_test(): mz(q) with pytest.raises(RuntimeError) as e: - counts = cudaq.sample(single_adjoint_test, shots_count=100) + cudaq.sample(single_adjoint_test, shots_count=100) assert "uses a gate: sdg which is not supported by the device or defined via a defcal" in repr( e) @@ -146,3 +146,28 @@ def rotation_adjoint_test(): counts = cudaq.sample(rotation_adjoint_test, shots_count=100) assert '0' in counts assert len(counts) == 1 + + +def test_u3_decomposition(): + + @cudaq.kernel + def kernel(): + qubit = cudaq.qubit() + u3(0.0, np.pi / 2, np.pi, qubit) + mz(qubit) + + # Test here is that this runs + result = cudaq.sample(kernel, shots_count=100) + measurement_probabilities = dict(result.items()) + print(measurement_probabilities) + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + u3.ctrl(0.0, np.pi / 2, np.pi, qubits[0], qubits[1]) + mz(qubits) + + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "uses a gate: crz which is not supported by the device or defined via a defcal" in repr( + e) diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 93ce0596e2..ed21941c8c 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition,combine-quantum-alloc,canonicalize),decomposition{enable-patterns=CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition,combine-quantum-alloc,canonicalize),decomposition{enable-patterns=U3ToRotations,CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From 2315af9cd7b8db0956c34388413f5d5057f4b46b Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 11:49:32 -0800 Subject: [PATCH 21/47] * Test for other simulators * Test for asynchronous sampling API * Failing test for observe API * More tests to cover all native gates, custom operations * One more test - check kernel that takes arguments Signed-off-by: Pradnya Khalate --- python/tests/backends/test_braket.py | 131 ++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 1 deletion(-) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 457a193ffe..546c3d195b 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -6,7 +6,10 @@ # the terms of the Apache License 2.0 which accompanies this distribution. # # ============================================================================ # -import cudaq, pytest, os +import cudaq +import pytest +import os +from cudaq import spin import numpy as np from multiprocessing import Process from network_utils import check_server_connection @@ -103,6 +106,40 @@ def test_builder_sample(): assert "11" in counts +def test_all_gates(): + + @cudaq.kernel + def single_qubit_gates(): + q = cudaq.qubit() + h(q) + x(q) + y(q) + z(q) + # r1(np.pi, q) ## Unsupported + rx(np.pi, q) + ry(np.pi, q) + rz(np.pi, q) + s(q) + t(q) + # mx(q) ## Unsupported + # my(q) ## Unsupported + mz(q) + + # Test here is that this runs + cudaq.sample(single_qubit_gates, shots_count=100).dump() + + @cudaq.kernel + def two_qubit_gates(): + qubits = cudaq.qvector(2) + x(qubits[0]) + swap(qubits[0], qubits[1]) + mz(qubits) + + counts = cudaq.sample(two_qubit_gates, shots_count=100) + assert len(counts) == 1 + assert "01" in counts + + def test_control_modifier(): @cudaq.kernel @@ -171,3 +208,95 @@ def kernel(): cudaq.sample(kernel, shots_count=100) assert "uses a gate: crz which is not supported by the device or defined via a defcal" in repr( e) + + +def test_sample_async(): + cudaq.set_random_seed(13) + + @cudaq.kernel + def simple(): + qubits = cudaq.qvector(2) + h(qubits[0]) + x.ctrl(qubits[0], qubits[1]) + mz(qubits) + + future = cudaq.sample_async(simple) + counts = future.get() + assert (len(counts) == 2) + assert ('00' in counts) + assert ('11' in counts) + + +def test_observe(): + cudaq.set_random_seed(13) + + @cudaq.kernel + def ansatz(theta: float): + qreg = cudaq.qvector(2) + x(qreg[0]) + ry(theta, qreg[1]) + x.ctrl(qreg[1], qreg[0]) + ## NOTE: Measure required since 'Device requires all qubits in the program to be measured.' + mz(qreg) + + # Define its spin Hamiltonian. + hamiltonian = 5.907 - 2.1433 * spin.x(0) * spin.x(1) - 2.1433 * spin.y( + 0) * spin.y(1) + .21829 * spin.z(0) - 6.125 * spin.z(1) + + with pytest.raises(RuntimeError) as e: + cudaq.observe(ansatz, hamiltonian, .59, shots_count=100) + assert "observe specification violated for 'ansatz': kernels passed to observe cannot have measurements specified." in repr( + e) + + +def test_custom_operations(): + + cudaq.register_operation("custom_x", np.array([0, 1, 1, 0])) + + @cudaq.kernel + def basic_x(): + qubit = cudaq.qubit() + custom_x(qubit) + + ## NOTE: `translateOperatorName` function in `lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp` + # replaces `r1` with `u1` + with pytest.raises(RuntimeError) as e: + cudaq.sample(basic_x, shots_count=100) + assert "uses a gate: u1 which is not supported by the device or defined via a defcal" in repr( + e) + + +def test_kernel_with_args(): + + @cudaq.kernel + def kernel(qubit_count: int): + qreg = cudaq.qvector(qubit_count) + h(qreg[0]) + for qubit in range(qubit_count - 1): + x.ctrl(qreg[qubit], qreg[qubit + 1]) + mz(qreg) + + counts = cudaq.sample(kernel, 8, shots_count=100) + assert len(counts) == 2 + assert "00000000" in counts + assert "11111111" in counts + + +@pytest.mark.parametrize("device_arn", [ + "arn:aws:braket:::device/quantum-simulator/amazon/dm1", + "arn:aws:braket:::device/quantum-simulator/amazon/tn1" +]) +def test_other_simulators(device_arn): + + cudaq.set_target("braket", machine=device_arn) + + test_qvector_kernel() + test_builder_sample() + + cudaq.reset_target() + + +# leave for gdb debugging +if __name__ == "__main__": + loc = os.path.abspath(__file__) + pytest.main([loc, "-s"]) From b79042e37c1e8596ceb69a0be327d4d6047df577 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 14:47:02 -0800 Subject: [PATCH 22/47] * Remove the `combine-quantum-alloc` pass since multiple registers are not supported. * Simplify test setup since mock server isn't being used. Signed-off-by: Pradnya Khalate --- python/tests/backends/test_braket.py | 46 ++++++++----------- .../default/rest/helpers/braket/braket.yml | 2 +- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 546c3d195b..2b8271fca0 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -19,31 +19,14 @@ ## NOTE: Amazon Braket costs apply pytestmark = pytest.mark.skip("Braket credentials required") -try: - from utils.mock_qpu.braket import startServer -except: - print("Mock qpu not available, skipping Braket tests.") - pytest.skip("Mock qpu not available.", allow_module_level=True) - -# Define the port for the mock server -port = 62445 - @pytest.fixture(scope="session", autouse=True) -def startUpMockServer(): - # NOTE: Credentials can be set with AWS CLI +def do_something(): device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" cudaq.set_target("braket", machine=device_arn) - # Launch the Mock Server - p = Process(target=startServer, args=(port,)) - p.start() - if not check_server_connection(port): - p.terminate() - pytest.exit("Mock server did not start in time, skipping tests.", - returncode=1) yield "Running the tests." - # Kill the server, remove the file - p.terminate() + cudaq.__clearKernelRegistries() + cudaq.reset_target() def test_simple_kernel(): @@ -74,7 +57,7 @@ def kernel(): with pytest.raises(RuntimeError) as e: cudaq.sample(kernel, shots_count=100) - assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( + assert "cannot declare a qubit register. Only 1 qubit register(s) is/are supported" in repr( e) @@ -140,6 +123,22 @@ def two_qubit_gates(): assert "01" in counts +def test_multi_qvector(): + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + ancilla = cudaq.qvector(2) + x(qubits) + h(ancilla) + mz(ancilla) + + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100) + assert "cannot declare a qubit register. Only 1 qubit register(s) is/are supported" in repr( + e) + + def test_control_modifier(): @cudaq.kernel @@ -174,10 +173,8 @@ def rotation_adjoint_test(): q = cudaq.qubit() rx(1.1, q) rx.adj(1.1, q) - ry(1.1, q) ry.adj(1.1, q) - mz(q) counts = cudaq.sample(rotation_adjoint_test, shots_count=100) @@ -287,12 +284,9 @@ def kernel(qubit_count: int): "arn:aws:braket:::device/quantum-simulator/amazon/tn1" ]) def test_other_simulators(device_arn): - cudaq.set_target("braket", machine=device_arn) - test_qvector_kernel() test_builder_sample() - cudaq.reset_target() diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index ed21941c8c..44903e032f 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition,combine-quantum-alloc,canonicalize),decomposition{enable-patterns=U3ToRotations,CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=U3ToRotations,CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From 1e653fe35b06c6594838e8703f86b00833f704f0 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Thu, 21 Nov 2024 15:47:49 -0800 Subject: [PATCH 23/47] * Clean-up test, use 'Amazon Braket' in messages Signed-off-by: Pradnya Khalate --- python/tests/backends/test_QuEra.py | 2 +- python/tests/backends/test_braket.py | 12 ++++-------- .../rest/helpers/braket/BraketServerHelper.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/python/tests/backends/test_QuEra.py b/python/tests/backends/test_QuEra.py index e80e11b1da..439c7ecd2c 100644 --- a/python/tests/backends/test_QuEra.py +++ b/python/tests/backends/test_QuEra.py @@ -40,7 +40,7 @@ def startUpMockServer(): p.terminate() -@pytest.mark.skip(reason="Braket credentials required") +@pytest.mark.skip(reason="Amazon Braket credentials required") def test_JSON_payload(): ''' Test based on https://docs.aws.amazon.com/braket/latest/developerguide/braket-quera-submitting-analog-program-aquila.html diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 2b8271fca0..551dcb3fc7 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -11,13 +11,11 @@ import os from cudaq import spin import numpy as np -from multiprocessing import Process -from network_utils import check_server_connection ## NOTE: Comment the following line which skips these tests in order to run in # local dev environment after setting AWS credentials. ## NOTE: Amazon Braket costs apply -pytestmark = pytest.mark.skip("Braket credentials required") +pytestmark = pytest.mark.skip("Amazon Braket credentials required") @pytest.fixture(scope="session", autouse=True) @@ -38,8 +36,6 @@ def kernel(): mz(q) counts = cudaq.sample(kernel, shots_count=100) - counts.dump() - assert len(counts) == 1 assert "1" in counts @@ -273,10 +269,10 @@ def kernel(qubit_count: int): x.ctrl(qreg[qubit], qreg[qubit + 1]) mz(qreg) - counts = cudaq.sample(kernel, 8, shots_count=100) + counts = cudaq.sample(kernel, 4, shots_count=100) assert len(counts) == 2 - assert "00000000" in counts - assert "11111111" in counts + assert "0000" in counts + assert "1111" in counts @pytest.mark.parametrize("device_arn", [ diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp index 76cfb680e6..26ba0ceb42 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp @@ -34,8 +34,8 @@ std::string getDeviceArn(const std::string &machine) { for (const auto &machine : deviceArns) knownMachines += machine.first + " "; const auto errorMessage = - fmt::format("Machine \"{}\" is invalid. Machine must be either a Braket " - "device ARN or one of the known devices: {}", + fmt::format("Machine \"{}\" is invalid. Machine must be either an Amazon " + "Braket device ARN or one of the known devices: {}", machine, knownMachines); throw std::runtime_error(errorMessage); } @@ -68,8 +68,8 @@ void BraketServerHelper::initialize(BackendConfig config) { const auto emulate_it = config.find("emulate"); if (emulate_it != config.end() && emulate_it->second == "true") { - cudaq::info("Emulation is enabled, ignore all Braket connection specific " - "information."); + cudaq::info("Emulation is enabled, ignore all Amazon Braket connection " + "specific information."); backendConfig = std::move(config); return; } From fbad12a584961814ec3ada0735baa520a82abb03 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Fri, 22 Nov 2024 12:00:45 -0800 Subject: [PATCH 24/47] * Decomposition patterns for R1, CRz, Sdg Co-authored-by: Bettina Heim Signed-off-by: Pradnya Khalate --- lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp | 4 +- .../Transforms/DecompositionPatterns.cpp | 49 +++++++++++++++++++ python/tests/backends/test_braket.py | 16 +++--- .../default/rest/helpers/braket/braket.yml | 2 +- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp index 04c431b0ab..e567f53d1e 100644 --- a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp +++ b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp @@ -23,13 +23,13 @@ using namespace cudaq; //===----------------------------------------------------------------------===// // Helper functions //===----------------------------------------------------------------------===// - +/// FIXME: Remove this code /// Translates operation names into OpenQASM gate names static LogicalResult translateOperatorName(quake::OperatorInterface optor, StringRef &name) { StringRef qkeName = optor->getName().stripDialect(); if (optor.getControls().size() == 0) { - name = StringSwitch(qkeName).Case("r1", "u1").Default(qkeName); + name = StringSwitch(qkeName).Default(qkeName); } else if (optor.getControls().size() == 1) { name = StringSwitch(qkeName) .Case("h", "ch") diff --git a/lib/Optimizer/Transforms/DecompositionPatterns.cpp b/lib/Optimizer/Transforms/DecompositionPatterns.cpp index bdf8e9244c..d1cfdb13ba 100644 --- a/lib/Optimizer/Transforms/DecompositionPatterns.cpp +++ b/lib/Optimizer/Transforms/DecompositionPatterns.cpp @@ -460,6 +460,25 @@ struct R1ToRz : public OpRewritePattern { } }; +// Naive mapping of R1 to U3, ignoring the global phase. +// This is only expected to work with full inlining and +// quake apply specialization. +struct R1ToU3 : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + void initialize() { setDebugName("R1ToU3"); } + + LogicalResult matchAndRewrite(quake::R1Op r1Op, + PatternRewriter &rewriter) const override { + Location loc = r1Op->getLoc(); + Value zero = createConstant(loc, 0.0, rewriter.getF64Type(), rewriter); + std::array parameters = {zero, zero, r1Op.getParameters()[0]}; + rewriter.replaceOpWithNewOp( + r1Op, r1Op.isAdj(), parameters, r1Op.getControls(), r1Op.getTargets()); + return success(); + } +}; + // quake.swap a, b // ─────────────────────────────────── // quake.cnot b, a; @@ -603,6 +622,34 @@ struct SToR1 : public OpRewritePattern { } }; +// quake.s target +// ───────────────────────────────── +// (quake.z * quake.s) target +struct SAdjToSZ : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + void initialize() { setDebugName("SAdjToSZ"); } + + LogicalResult matchAndRewrite(quake::SOp op, + PatternRewriter &rewriter) const override { + if (!op.isAdj()) + return failure(); + + // Op info + auto loc = op->getLoc(); + auto parameters = op.getParameters(); + SmallVector controls(op.getControls()); + Value target = op.getTarget(); + + QuakeOperatorCreator qRewriter(rewriter); + qRewriter.create(loc, parameters, controls, target); + qRewriter.create(loc, parameters, controls, target); + qRewriter.selectWiresAndReplaceUses(op, controls, target); + rewriter.eraseOp(op); + return success(); + } +}; + //===----------------------------------------------------------------------===// // TOp decompositions //===----------------------------------------------------------------------===// @@ -1537,6 +1584,7 @@ void cudaq::populateWithAllDecompositionPatterns(RewritePatternSet &patterns) { // SOp patterns SToPhasedRx, SToR1, + SAdjToSZ, // TOp patterns TToPhasedRx, TToR1, @@ -1554,6 +1602,7 @@ void cudaq::populateWithAllDecompositionPatterns(RewritePatternSet &patterns) { CR1ToCX, R1ToPhasedRx, R1ToRz, + R1ToU3, // RxOp patterns CRxToCX, RxToPhasedRx, diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 551dcb3fc7..5fd216c5b1 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -94,7 +94,7 @@ def single_qubit_gates(): x(q) y(q) z(q) - # r1(np.pi, q) ## Unsupported + r1(np.pi, q) rx(np.pi, q) ry(np.pi, q) rz(np.pi, q) @@ -159,10 +159,9 @@ def single_adjoint_test(): s.adj(q) mz(q) - with pytest.raises(RuntimeError) as e: - cudaq.sample(single_adjoint_test, shots_count=100) - assert "uses a gate: sdg which is not supported by the device or defined via a defcal" in repr( - e) + counts = cudaq.sample(single_adjoint_test, shots_count=100) + assert len(counts) == 1 + assert "0" in counts @cudaq.kernel def rotation_adjoint_test(): @@ -197,10 +196,9 @@ def kernel(): u3.ctrl(0.0, np.pi / 2, np.pi, qubits[0], qubits[1]) mz(qubits) - with pytest.raises(RuntimeError) as e: - cudaq.sample(kernel, shots_count=100) - assert "uses a gate: crz which is not supported by the device or defined via a defcal" in repr( - e) + counts = cudaq.sample(kernel, shots_count=100) + assert '00' in counts + assert len(counts) == 1 def test_sample_async(): diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 44903e032f..09ee016649 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=U3ToRotations,CCZToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From aef659e315f4453dbfc643295e71794504f36119 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Fri, 22 Nov 2024 14:33:29 -0800 Subject: [PATCH 25/47] * Addd `tdg` decomposition Signed-off-by: Pradnya Khalate --- .../Transforms/DecompositionPatterns.cpp | 28 +++++++++ python/tests/backends/test_braket.py | 63 ++++++++++++------- .../default/rest/helpers/braket/braket.yml | 2 +- 3 files changed, 68 insertions(+), 25 deletions(-) diff --git a/lib/Optimizer/Transforms/DecompositionPatterns.cpp b/lib/Optimizer/Transforms/DecompositionPatterns.cpp index d1cfdb13ba..034a0d5bb7 100644 --- a/lib/Optimizer/Transforms/DecompositionPatterns.cpp +++ b/lib/Optimizer/Transforms/DecompositionPatterns.cpp @@ -726,6 +726,33 @@ struct TToR1 : public OpRewritePattern { } }; +// quake.tdg [control] target +// ──────────────────────────────────── +// quake.r1(-π/4) [control] target +struct TAdjToR1 : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + void initialize() { setDebugName("TAdjToR1"); } + + LogicalResult matchAndRewrite(quake::TOp op, + PatternRewriter &rewriter) const override { + if (!op.isAdj()) + return failure(); + + // Op info + auto loc = op->getLoc(); + SmallVector controls(op.getControls()); + Value target = op.getTarget(); + + QuakeOperatorCreator qRewriter(rewriter); + Value angle = createConstant(loc, -M_PI_4, rewriter.getF64Type(), rewriter); + qRewriter.create(loc, angle, controls, target); + qRewriter.selectWiresAndReplaceUses(op, controls, target); + rewriter.eraseOp(op); + return success(); + } +}; + //===----------------------------------------------------------------------===// // XOp decompositions //===----------------------------------------------------------------------===// @@ -1588,6 +1615,7 @@ void cudaq::populateWithAllDecompositionPatterns(RewritePatternSet &patterns) { // TOp patterns TToPhasedRx, TToR1, + TAdjToR1, // XOp patterns CXToCZ, CCXToCCZ, diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 5fd216c5b1..2d2bb02a77 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -137,6 +137,34 @@ def kernel(): def test_control_modifier(): + @cudaq.kernel + def single_qubit_gates(): + qubits = cudaq.qvector(2) + h.ctrl(qubits[0], qubits[1]) + x.ctrl(qubits[1], qubits[0]) + y.ctrl(qubits[0], qubits[1]) + z.ctrl(qubits[1], qubits[0]) + r1.ctrl(np.pi / 2, qubits[0], qubits[1]) + rx.ctrl(np.pi / 4, qubits[1], qubits[0]) + ry.ctrl(np.pi / 8, qubits[0], qubits[1]) + rz.ctrl(np.pi, qubits[1], qubits[0]) + s.ctrl(qubits[0], qubits[1]) + t.ctrl(qubits[1], qubits[0]) + mz(qubits) + + # Test here is that this runs + cudaq.sample(single_qubit_gates, shots_count=100).dump() + + @cudaq.kernel + def test(): + qubits = cudaq.qvector(3) + x(qubits[0], qubits[1]) + swap.ctrl(qubits[0], qubits[1], qubits[2]) + + counts = cudaq.sample(test) + assert len(counts) == 1 + assert '110' in counts + @cudaq.kernel def bell(): qubits = cudaq.qvector(2) @@ -153,28 +181,18 @@ def bell(): def test_adjoint_modifier(): @cudaq.kernel - def single_adjoint_test(): + def single_qubit_gates(): q = cudaq.qubit() - s(q) + r1.adj(np.pi, q) + rx.adj(np.pi / 2, q) + ry.adj(np.pi / 4, q) + rz.adj(np.pi / 8, q) s.adj(q) + t.adj(q) mz(q) - counts = cudaq.sample(single_adjoint_test, shots_count=100) - assert len(counts) == 1 - assert "0" in counts - - @cudaq.kernel - def rotation_adjoint_test(): - q = cudaq.qubit() - rx(1.1, q) - rx.adj(1.1, q) - ry(1.1, q) - ry.adj(1.1, q) - mz(q) - - counts = cudaq.sample(rotation_adjoint_test, shots_count=100) - assert '0' in counts - assert len(counts) == 1 + # Test here is that this runs + cudaq.sample(single_qubit_gates, shots_count=100).dump() def test_u3_decomposition(): @@ -248,13 +266,10 @@ def test_custom_operations(): def basic_x(): qubit = cudaq.qubit() custom_x(qubit) + mz(qubit) - ## NOTE: `translateOperatorName` function in `lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp` - # replaces `r1` with `u1` - with pytest.raises(RuntimeError) as e: - cudaq.sample(basic_x, shots_count=100) - assert "uses a gate: u1 which is not supported by the device or defined via a defcal" in repr( - e) + counts = cudaq.sample(basic_x, shots_count=100) + assert len(counts) == 1 and "1" in counts def test_kernel_with_args(): diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 09ee016649..6b23360e5b 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=SAdjToSZ,TAdjToR1,R1ToU3,U3ToRotations,CCZToCX,CRzToCX,CRxToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From 89ac10e35a77b1899359b577739fc63042706a93 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Fri, 22 Nov 2024 16:10:11 -0800 Subject: [PATCH 26/47] * Control modifier fixes Signed-off-by: Pradnya Khalate --- lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp | 10 +++------- python/tests/backends/test_braket.py | 12 +++++++----- .../platform/default/rest/helpers/braket/braket.yml | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp index e567f53d1e..631118a2c5 100644 --- a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp +++ b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp @@ -23,7 +23,7 @@ using namespace cudaq; //===----------------------------------------------------------------------===// // Helper functions //===----------------------------------------------------------------------===// -/// FIXME: Remove this code +/// FIXME: Remove this code, move logic to decomposition patterns /// Translates operation names into OpenQASM gate names static LogicalResult translateOperatorName(quake::OperatorInterface optor, StringRef &name) { @@ -32,15 +32,11 @@ static LogicalResult translateOperatorName(quake::OperatorInterface optor, name = StringSwitch(qkeName).Default(qkeName); } else if (optor.getControls().size() == 1) { name = StringSwitch(qkeName) - .Case("h", "ch") .Case("x", "cx") .Case("y", "cy") .Case("z", "cz") - .Case("r1", "cu1") - .Case("rx", "crx") - .Case("ry", "cry") - .Case("rz", "crz") - .Default(""); + .Case("swap", "cswap") + .Default(qkeName); } else if (optor.getControls().size() == 2) { name = StringSwitch(qkeName).Case("x", "ccx").Default(""); } diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 2d2bb02a77..d730358c01 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -156,14 +156,16 @@ def single_qubit_gates(): cudaq.sample(single_qubit_gates, shots_count=100).dump() @cudaq.kernel - def test(): + def two_qubit_gates(): qubits = cudaq.qvector(3) - x(qubits[0], qubits[1]) + x(qubits[0]) + x(qubits[1]) swap.ctrl(qubits[0], qubits[1], qubits[2]) + mz(qubits) - counts = cudaq.sample(test) + counts = cudaq.sample(two_qubit_gates, shots_count=100) assert len(counts) == 1 - assert '110' in counts + assert '101' in counts @cudaq.kernel def bell(): @@ -229,7 +231,7 @@ def simple(): x.ctrl(qubits[0], qubits[1]) mz(qubits) - future = cudaq.sample_async(simple) + future = cudaq.sample_async(simple, shots_count=100) counts = future.get() assert (len(counts) == 2) assert ('00' in counts) diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 6b23360e5b..519d81d4ea 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=SAdjToSZ,TAdjToR1,R1ToU3,U3ToRotations,CCZToCX,CRzToCX,CRxToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=SToR1,TToR1,SAdjToSZ,TAdjToR1,R1ToU3,U3ToRotations,CHToCX,CCZToCX,CRzToCX,CRyToCX,CRxToCX,CR1ToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off From 304482e37dac587af120a1bb0b0307ab21367107 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Fri, 22 Nov 2024 16:23:15 -0800 Subject: [PATCH 27/47] * More tests Signed-off-by: Pradnya Khalate --- python/tests/backends/test_braket.py | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index d730358c01..bfe6ce7835 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -290,6 +290,36 @@ def kernel(qubit_count: int): assert "1111" in counts +def test_qvector_slicing(): + + @cudaq.kernel + def kernel(): + q = cudaq.qvector(4) + x(q.front(2)) + mz(q) + + ## error: 'quake.subveq' op unable to translate op to OpenQASM 2.0 + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100).dump() + assert "Could not successfully translate to qasm2" in repr(e) + + +def test_mid_circuit_measurement(): + + @cudaq.kernel + def simple(): + q = cudaq.qvector(2) + h(q[0]) + if mz(q[0]): + x(q[1]) + mz(q) + + ## error: 'cf.cond_br' op unable to translate op to OpenQASM 2.0 + with pytest.raises(RuntimeError) as e: + cudaq.sample(simple, shots_count=100).dump() + assert "Could not successfully translate to qasm2" in repr(e) + + @pytest.mark.parametrize("device_arn", [ "arn:aws:braket:::device/quantum-simulator/amazon/dm1", "arn:aws:braket:::device/quantum-simulator/amazon/tn1" From 499f420735265e08b0e6f076e77344c3fd744201 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Fri, 22 Nov 2024 16:32:59 -0800 Subject: [PATCH 28/47] * Failing test for multiple measurement ops Signed-off-by: Pradnya Khalate --- python/tests/backends/test_braket.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index bfe6ce7835..4d7ed420d5 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -290,6 +290,21 @@ def kernel(qubit_count: int): assert "1111" in counts +def test_multiple_measurement(): + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + h(qubits[0]) + mz(qubits[0]) + mz(qubits[1]) + + with pytest.raises(RuntimeError) as e: + cudaq.sample(kernel, shots_count=100).dump() + assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( + e) + + def test_qvector_slicing(): @cudaq.kernel From 69a0277df4f78bf3d398cfb2bb39d50e175f2c06 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate <148914294+khalatepradnya@users.noreply.github.com> Date: Fri, 22 Nov 2024 16:23:53 -0800 Subject: [PATCH 29/47] Update lib/Optimizer/Transforms/DecompositionPatterns.cpp Co-authored-by: Eric Schweitz Signed-off-by: Pradnya Khalate <148914294+khalatepradnya@users.noreply.github.com> --- lib/Optimizer/Transforms/DecompositionPatterns.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Optimizer/Transforms/DecompositionPatterns.cpp b/lib/Optimizer/Transforms/DecompositionPatterns.cpp index 034a0d5bb7..845b07093f 100644 --- a/lib/Optimizer/Transforms/DecompositionPatterns.cpp +++ b/lib/Optimizer/Transforms/DecompositionPatterns.cpp @@ -622,9 +622,10 @@ struct SToR1 : public OpRewritePattern { } }; -// quake.s target +// quake.s [control] target // ───────────────────────────────── -// (quake.z * quake.s) target +// quake.z [control] target +// quake.s [control] target struct SAdjToSZ : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; From 9fd113faaeac2dff20c79114b8e33bbc6d3714e1 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Sun, 24 Nov 2024 12:16:06 -0800 Subject: [PATCH 30/47] Add combine-measurements pass Signed-off-by: Anna Gringauze --- include/cudaq/Optimizer/Transforms/Passes.td | 10 + lib/Optimizer/CodeGen/Pipelines.cpp | 5 +- lib/Optimizer/Transforms/CMakeLists.txt | 1 + .../Transforms/CombineMeasurements.cpp | 136 +++ program.py | 256 +++++ python/tests/backends/test_braket.py | 16 + runtime/common/BaseRemoteRESTQPU.h | 19 +- runtime/common/RuntimeMLIRCommonImpl.h | 8 + .../rest/helpers/braket/BraketExecutor.cpp | 157 +-- .../helpers/braket/BraketServerHelper.cpp | 86 +- .../default/rest/helpers/braket/braket.yml | 2 + tmp.qke | 17 + tmp.txt | 970 ++++++++++++++++++ 13 files changed, 1603 insertions(+), 80 deletions(-) create mode 100644 lib/Optimizer/Transforms/CombineMeasurements.cpp create mode 100644 program.py create mode 100644 tmp.qke create mode 100644 tmp.txt diff --git a/include/cudaq/Optimizer/Transforms/Passes.td b/include/cudaq/Optimizer/Transforms/Passes.td index 15724c6484..73ca0289ac 100644 --- a/include/cudaq/Optimizer/Transforms/Passes.td +++ b/include/cudaq/Optimizer/Transforms/Passes.td @@ -141,6 +141,16 @@ def CheckKernelCalls : Pass<"check-kernel-calls", "mlir::func::FuncOp"> { }]; } +def CombineMeasurements : + Pass<"combine-measurements", "mlir::func::FuncOp"> { + let summary = "Combines mz operations and removes subveqs."; + let description = [{ + TODO + }]; + let dependentDialects = ["cudaq::cc::CCDialect", "quake::QuakeDialect"]; +} + + def CombineQuantumAllocations : Pass<"combine-quantum-alloc", "mlir::func::FuncOp"> { let summary = "Combines quake alloca operations."; diff --git a/lib/Optimizer/CodeGen/Pipelines.cpp b/lib/Optimizer/CodeGen/Pipelines.cpp index 662061dc7a..c0e93517fe 100644 --- a/lib/Optimizer/CodeGen/Pipelines.cpp +++ b/lib/Optimizer/CodeGen/Pipelines.cpp @@ -41,6 +41,7 @@ void cudaq::opt::commonPipelineConvertToQIR( pm.addPass(createConvertToQIR()); } +// TODO: remove passes from yml files? void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) { pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); @@ -57,9 +58,10 @@ void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) { pm.addPass(createCSEPass()); pm.addNestedPass(createMultiControlDecompositionPass()); pm.addPass(createDecompositionPass( - {.enabledPatterns = {"CCZToCX", "RxAdjToRx", "RyAdjToRy", "RzAdjToRz"}})); + {.enabledPatterns = {"R1ToU3","U3ToRotations","CCZToCX","CRzToCX", "RxAdjToRx", "RyAdjToRy", "RzAdjToRz", "SAdjToSZ"}})); pm.addNestedPass(createExpandControlVeqs()); pm.addNestedPass(createCombineQuantumAllocations()); + pm.addNestedPass(createCombineMeasurements()); pm.addNestedPass(createCanonicalizerPass()); } @@ -72,6 +74,5 @@ void cudaq::opt::addPipelineTranslateToIQMJson(PassManager &pm) { pm.addNestedPass(createLowerToCFGPass()); pm.addNestedPass(createQuakeAddDeallocs()); pm.addNestedPass(createCombineQuantumAllocations()); - pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); } diff --git a/lib/Optimizer/Transforms/CMakeLists.txt b/lib/Optimizer/Transforms/CMakeLists.txt index d906b749e6..82c0e96d1e 100644 --- a/lib/Optimizer/Transforms/CMakeLists.txt +++ b/lib/Optimizer/Transforms/CMakeLists.txt @@ -17,6 +17,7 @@ add_cudaq_library(OptTransforms ApplyOpSpecialization.cpp ArgumentSynthesis.cpp BasisConversion.cpp + CombineMeasurements.cpp CombineQuantumAlloc.cpp ConstPropComplex.cpp Decomposition.cpp diff --git a/lib/Optimizer/Transforms/CombineMeasurements.cpp b/lib/Optimizer/Transforms/CombineMeasurements.cpp new file mode 100644 index 0000000000..37aea3db7c --- /dev/null +++ b/lib/Optimizer/Transforms/CombineMeasurements.cpp @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * + * All rights reserved. * + * * + * This source code and the accompanying materials are made available under * + * the terms of the Apache License 2.0 which accompanies this distribution. * + ******************************************************************************/ + +#include "PassDetails.h" +//#include "cudaq/Optimizer/Builder/Runtime.h" +#include "cudaq/Optimizer/CodeGen/QIRAttributeNames.h" +//#include "cudaq/Optimizer/CodeGen/CudaqFunctionNames.h" +#include "cudaq/Optimizer/Dialect/CC/CCOps.h" +#include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h" +#include "cudaq/Optimizer/Dialect/Quake/QuakeTypes.h" +#include "cudaq/Optimizer/Transforms/Passes.h" +#include "llvm/Support/Debug.h" +//#include "mlir/Conversion/LLVMCommon/TypeConverter.h" +#include "mlir/Dialect/Arith/IR/Arith.h" +//#include "mlir/Dialect/Complex/IR/Complex.h" +#include "mlir/Dialect/Func/IR/FuncOps.h" +//#include "mlir/Dialect/Math/IR/Math.h" +#include "mlir/Pass/Pass.h" +//#include "mlir/Target/LLVMIR/TypeToLLVM.h" +//#include "mlir/Transforms/DialectConversion.h" +#include "mlir/Transforms/GreedyPatternRewriteDriver.h" +#include "mlir/Transforms/Passes.h" +//#include "mlir/Transforms/RegionUtils.h" +#include "nlohmann/json.hpp" + +namespace cudaq::opt { +#define GEN_PASS_DEF_COMBINEMEASUREMENTS +#include "cudaq/Optimizer/Transforms/Passes.h.inc" +} // namespace cudaq::opt + +#define DEBUG_TYPE "combine-measurements" + +using namespace mlir; + +namespace { + +class ExtendMeasurePattern : public OpRewritePattern { + using OutputNamesType = + std::map>; +public: + using OpRewritePattern::OpRewritePattern; + + explicit ExtendMeasurePattern(MLIRContext *ctx, OutputNamesType &resultQubitVals) + : OpRewritePattern(ctx), + resultQubitVals(resultQubitVals) {} + + // Replace a pattern such as: + // ``` + // func.func @kernel() attributes {"cudaq-entrypoint"} { + // %1 = ... : !quake.veq<4> + // %2 = quake.subveq %1, %c2, %c3 : (!quake.veq<4>, i32, i32) -> + // !quake.veq<2> + // %measOut = quake.mz %2 : (!quake.veq<2>) -> !cc.stdvec + // } + // ``` + // with: + // ``` + // func.func @kernel() attributes {"cudaq-entrypoint", ["output_names", "[[[0,[1,\22q0\22]],[1,[2,\22q1\22]]]]"]} { + // %1 = ... : !quake.veq<4> + // %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec + // } + // ``` + LogicalResult matchAndRewrite(quake::MzOp measure, + PatternRewriter &rewriter) const override { + if (!measure.use_empty()) { + measure.emitError("Only measures with no uses are supported"); + return failure(); + } + + auto veqOp = measure.getOperand(0); + if (auto subveq = veqOp.getDefiningOp()) { + Value lowOp = subveq.getLow(); + Value highOp = subveq.getHigh(); + if (auto constLow = lowOp.getDefiningOp()) { + auto low = static_cast(constLow.value()); + if (auto constHigh = highOp.getDefiningOp()) { + auto high = static_cast(constHigh.value()); + for (std::size_t i = low; i <= high; i++) { + // Note: regname is ignored for OpenQasm2 + resultQubitVals[i-low] = std::make_pair(i, std::to_string(i)); + } + rewriter.replaceOpWithNewOp(measure, measure.getResultTypes(), subveq.getVeq()); + return success(); + } + } + } + + return failure(); + } +private: + OutputNamesType &resultQubitVals; +}; + + +class CombineMeasurementsPass + : public cudaq::opt::impl::CombineMeasurementsBase< + CombineMeasurementsPass> { + using OutputNamesType = + std::map>; +public: + using CombineMeasurementsBase::CombineMeasurementsBase; + + void runOnOperation() override { + auto *ctx = &getContext(); + func::FuncOp func = getOperation(); + OpBuilder builder(func); + + LLVM_DEBUG(llvm::dbgs() << "Function before combining measurements:\n" + << func << "\n\n"); + + RewritePatternSet patterns(ctx); + OutputNamesType resultQubitVals; + patterns.insert(ctx, resultQubitVals); + if (failed(applyPatternsAndFoldGreedily(func.getOperation(), + std::move(patterns)))) { + func.emitOpError("combining measurements failed"); + signalPassFailure(); + } + + // TODO: move measOut to the end of the func (see delayMeasurements?) + if (!resultQubitVals.empty()) { + nlohmann::json resultQubitJSON{resultQubitVals}; + func->setAttr(cudaq::opt::QIROutputNamesAttrName, + builder.getStringAttr(resultQubitJSON.dump())); + } + + LLVM_DEBUG(llvm::dbgs() << "Function after combining measurements:\n" + << func << "\n\n"); + } +}; +} // namespace diff --git a/program.py b/program.py new file mode 100644 index 0000000000..3cb82ce50e --- /dev/null +++ b/program.py @@ -0,0 +1,256 @@ +# ============================================================================ # +# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. # +# All rights reserved. # +# # +# This source code and the accompanying materials are made available under # +# the terms of the Apache License 2.0 which accompanies this distribution. # +# ============================================================================ # + +import cudaq + +def test_kernel_subveqs(): + device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" + #device_arn = "arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet" + cudaq.set_target("braket", machine=device_arn) + #cudaq.set_target("ionq", emulate=True) + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(4) + #h(qubits[0]) + # for qubit in range(3): + # x.ctrl(qubits[qubit], qubits[qubit + 1]) + x(qubits[1]) + x(qubits[2]) + v = qubits[1:3] + mz(v) + #mz(qubits) + + counts = cudaq.sample(kernel, shots_count=100) + print(counts) + # assert len(counts) == 2 + # assert "0000" in counts + # assert "1111" in counts + +test_kernel_subveqs() + +def test_kernel_veqs(): + device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" + cudaq.set_target("braket", emulate=True, machine=device_arn) + #cudaq.set_target("braket", machine=device_arn) + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + h(qubits[0]) + cx(qubits[0], qubits[1]) + mz(qubits) + + result = cudaq.sample(kernel, shots_count=1000) + print(result) + +#test_kernel_veqs() + +# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { +# func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { +# %c1_i64 = arith.constant 1 : i64 +# %0 = quake.alloca !quake.veq<4> +# %1 = quake.extract_ref %0[0] : (!quake.veq<4>) -> !quake.ref +# quake.h %1 : (!quake.ref) -> () +# %2 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref +# quake.x [%1] %2 : (!quake.ref, !quake.ref) -> () +# %3 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref +# quake.x [%2] %3 : (!quake.ref, !quake.ref) -> () +# %4 = quake.extract_ref %0[3] : (!quake.veq<4>) -> !quake.ref +# quake.x [%3] %4 : (!quake.ref, !quake.ref) -> () +# %5 = quake.subveq %0, %c1_i64, %c1_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<1> +# %measOut = quake.mz %5 : (!quake.veq<1>) -> !cc.stdvec +# return +# } +# } + +# => + +# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { +# func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { +# %c1_i64 = arith.constant 1 : i64 +# %0 = quake.alloca !quake.veq<4> +# %1 = quake.extract_ref %0[0] : (!quake.veq<4>) -> !quake.ref +# quake.h %1 : (!quake.ref) -> () +# %2 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref +# quake.x [%1] %2 : (!quake.ref, !quake.ref) -> () +# %3 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref +# quake.x [%2] %3 : (!quake.ref, !quake.ref) -> () +# %4 = quake.extract_ref %0[3] : (!quake.veq<4>) -> !quake.ref +# quake.x [%3] %4 : (!quake.ref, !quake.ref) -> () +# #%5 = quake.subveq %0, %c1_i64, %c1_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<1> +# %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec # add mapping to output only %0[1] +# return +# } +# } + +# // -----// IR Dump After ConvertToQIR (quake-to-qir) ('builtin.module' operation) //----- // +# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { +# llvm.func @__quantum__rt__qubit_release_array(!llvm.ptr>) +# llvm.func @__quantum__qis__mz(!llvm.ptr>) -> !llvm.ptr> +# llvm.func @invokeWithControlQubits(i64, !llvm.ptr>, ptr>)>>, ...) +# llvm.func @__quantum__qis__x__ctl(!llvm.ptr>, !llvm.ptr>) +# llvm.func @__quantum__qis__h(!llvm.ptr>) +# llvm.func @__quantum__rt__array_get_element_ptr_1d(!llvm.ptr>, i64) -> !llvm.ptr +# llvm.func @__quantum__rt__qubit_allocate_array(i64) -> !llvm.ptr> +# llvm.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { +# %0 = llvm.mlir.constant(4 : i64) : i64 +# %1 = llvm.call @__quantum__rt__qubit_allocate_array(%0) : (i64) -> !llvm.ptr> +# %2 = llvm.mlir.constant(0 : i64) : i64 +# %3 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %2) : (!llvm.ptr>, i64) -> !llvm.ptr +# %4 = llvm.bitcast %3 : !llvm.ptr to !llvm.ptr>> +# %5 = llvm.load %4 : !llvm.ptr>> +# llvm.call @__quantum__qis__h(%5) : (!llvm.ptr>) -> () +# %6 = llvm.mlir.constant(1 : i64) : i64 +# %7 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %6) : (!llvm.ptr>, i64) -> !llvm.ptr +# %8 = llvm.bitcast %7 : !llvm.ptr to !llvm.ptr>> +# %9 = llvm.load %8 : !llvm.ptr>> +# %10 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> +# %11 = llvm.mlir.constant(1 : i64) : i64 +# llvm.call @invokeWithControlQubits(%11, %10, %5, %9) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () +# %12 = llvm.mlir.constant(2 : i64) : i64 +# %13 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %12) : (!llvm.ptr>, i64) -> !llvm.ptr +# %14 = llvm.bitcast %13 : !llvm.ptr to !llvm.ptr>> +# %15 = llvm.load %14 : !llvm.ptr>> +# %16 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> +# %17 = llvm.mlir.constant(1 : i64) : i64 +# llvm.call @invokeWithControlQubits(%17, %16, %9, %15) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () +# %18 = llvm.mlir.constant(3 : i64) : i64 +# %19 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %18) : (!llvm.ptr>, i64) -> !llvm.ptr +# %20 = llvm.bitcast %19 : !llvm.ptr to !llvm.ptr>> +# %21 = llvm.load %20 : !llvm.ptr>> +# %22 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> +# %23 = llvm.mlir.constant(1 : i64) : i64 +# llvm.call @invokeWithControlQubits(%23, %22, %15, %21) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () +# %24 = llvm.mlir.constant(1 : i32) : i32 +# %25 = llvm.alloca %24 x !llvm.array<2 x i8> : (i32) -> !llvm.ptr> +# %26 = llvm.mlir.addressof @cstr.72303030303000 : !llvm.ptr> +# %27 = llvm.bitcast %26 : !llvm.ptr> to !llvm.ptr +# %28 = llvm.call @__quantum__qis__mz(%9) {registerName = "r00000"} : (!llvm.ptr>) -> !llvm.ptr> +# %29 = llvm.bitcast %28 : !llvm.ptr> to !llvm.ptr +# %30 = llvm.load %29 : !llvm.ptr +# %31 = llvm.bitcast %25 : !llvm.ptr> to !llvm.ptr +# %32 = llvm.zext %30 : i1 to i8 +# llvm.store %32, %31 : !llvm.ptr +# %33 = llvm.mlir.addressof @cstr.72303030303100 : !llvm.ptr> +# %34 = llvm.bitcast %33 : !llvm.ptr> to !llvm.ptr +# %35 = llvm.call @__quantum__qis__mz(%15) {registerName = "r00001"} : (!llvm.ptr>) -> !llvm.ptr> +# %36 = llvm.bitcast %35 : !llvm.ptr> to !llvm.ptr +# %37 = llvm.load %36 : !llvm.ptr +# %38 = llvm.getelementptr %25[0, 1] : (!llvm.ptr>) -> !llvm.ptr +# %39 = llvm.zext %37 : i1 to i8 +# llvm.store %39, %38 : !llvm.ptr +# llvm.call @__quantum__rt__qubit_release_array(%1) : (!llvm.ptr>) -> () +# llvm.return +# } +# llvm.mlir.global private constant @cstr.72303030303000("r00000\00") {addr_space = 0 : i32} +# llvm.mlir.global private constant @cstr.72303030303100("r00001\00") {addr_space = 0 : i32} +# } + +# // -----// IR Dump After Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { +# func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { +# %c2_i64 = arith.constant 2 : i64 +# %c1_i64 = arith.constant 1 : i64 +# %0 = quake.alloca !quake.veq<4> +# %1 = quake.extract_ref %0[0] : (!quake.veq<4>) -> !quake.ref +# quake.h %1 : (!quake.ref) -> () +# %2 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref +# quake.x [%1] %2 : (!quake.ref, !quake.ref) -> () +# %3 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref +# quake.x [%2] %3 : (!quake.ref, !quake.ref) -> () +# %4 = quake.extract_ref %0[3] : (!quake.veq<4>) -> !quake.ref +# quake.x [%3] %4 : (!quake.ref, !quake.ref) -> () +# %5 = quake.subveq %0, %c1_i64, %c2_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<2> +# %measOut = quake.mz %5 : (!quake.veq<2>) -> !cc.stdvec +# return +# } +# } + +# // IONQ: + + +# // -----// IR Dump After QIRToQIRProfileFunc (quake-to-qir-func) ('llvm.func' operation: @__nvqpp__mlirgen__kernel) //----- // +# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { +# llvm.func @__quantum__qis__h__body(!llvm.ptr>) +# llvm.func @__quantum__qis__cnot__body(!llvm.ptr>, !llvm.ptr>) +# llvm.func @__quantum__qis__cz__body(!llvm.ptr>, !llvm.ptr>) +# llvm.func @__quantum__rt__result_record_output(!llvm.ptr>, !llvm.ptr) +# llvm.func @__quantum__qis__read_result__body(!llvm.ptr>) -> i1 +# llvm.func @__quantum__qis__mz__body(!llvm.ptr>, !llvm.ptr>) attributes {passthrough = ["irreversible"]} +# llvm.func @__quantum__qis__cz(!llvm.ptr>, !llvm.ptr>) +# llvm.func @__quantum__qis__cnot(!llvm.ptr>, !llvm.ptr>) +# llvm.func @__quantum__rt__qubit_release_array(!llvm.ptr>) +# llvm.func @__quantum__qis__mz(!llvm.ptr>) -> !llvm.ptr> attributes {passthrough = ["irreversible"]} +# llvm.func @invokeWithControlQubits(i64, !llvm.ptr>, ptr>)>>, ...) +# llvm.func @__quantum__qis__x__ctl(!llvm.ptr>, !llvm.ptr>) +# llvm.func @__quantum__qis__h(!llvm.ptr>) +# llvm.func @__quantum__rt__array_get_element_ptr_1d(!llvm.ptr>, i64) -> !llvm.ptr +# llvm.func @__quantum__rt__qubit_allocate_array(i64) -> !llvm.ptr> +# llvm.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", passthrough = ["entry_point", ["qir_profiles", "base_profile"], ["output_labeling_schema", "schema_id"], ["output_names", "[[[0,[1,\22r00000\22]],[1,[2,\22r00001\22]]]]"], ["requiredQubits", "4"], ["requiredResults", "2"]]} { +# %0 = llvm.mlir.constant(4 : i64) : i64 +# %1 = llvm.call @__quantum__rt__qubit_allocate_array(%0) {StartingOffset = 0 : i64} : (i64) -> !llvm.ptr> +# %2 = llvm.mlir.constant(0 : i64) : i64 +# %3 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %2) : (!llvm.ptr>, i64) -> !llvm.ptr +# %4 = llvm.bitcast %3 : !llvm.ptr to !llvm.ptr>> +# %5 = llvm.load %4 : !llvm.ptr>> +# llvm.call @__quantum__qis__h(%5) : (!llvm.ptr>) -> () +# %6 = llvm.mlir.constant(1 : i64) : i64 +# %7 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %6) : (!llvm.ptr>, i64) -> !llvm.ptr +# %8 = llvm.bitcast %7 : !llvm.ptr to !llvm.ptr>> +# %9 = llvm.load %8 : !llvm.ptr>> +# %10 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> +# %11 = llvm.mlir.constant(1 : i64) : i64 +# llvm.call @invokeWithControlQubits(%11, %10, %5, %9) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () +# %12 = llvm.mlir.constant(2 : i64) : i64 +# %13 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %12) : (!llvm.ptr>, i64) -> !llvm.ptr +# %14 = llvm.bitcast %13 : !llvm.ptr to !llvm.ptr>> +# %15 = llvm.load %14 : !llvm.ptr>> +# %16 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> +# %17 = llvm.mlir.constant(1 : i64) : i64 +# llvm.call @invokeWithControlQubits(%17, %16, %9, %15) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () +# %18 = llvm.mlir.constant(3 : i64) : i64 +# %19 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %18) : (!llvm.ptr>, i64) -> !llvm.ptr +# %20 = llvm.bitcast %19 : !llvm.ptr to !llvm.ptr>> +# %21 = llvm.load %20 : !llvm.ptr>> +# %22 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> +# %23 = llvm.mlir.constant(1 : i64) : i64 +# llvm.call @invokeWithControlQubits(%23, %22, %15, %21) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () +# %24 = llvm.mlir.constant(1 : i32) : i32 +# %25 = llvm.alloca %24 x !llvm.array<2 x i8> : (i32) -> !llvm.ptr> +# %26 = llvm.bitcast %25 : !llvm.ptr> to !llvm.ptr +# %27 = llvm.getelementptr %25[0, 1] : (!llvm.ptr>) -> !llvm.ptr +# %28 = llvm.mlir.addressof @cstr.72303030303000 : !llvm.ptr> +# %29 = llvm.bitcast %28 : !llvm.ptr> to !llvm.ptr +# %30 = llvm.call @__quantum__qis__mz(%9) {registerName = "r00000", result.index = 0 : i64} : (!llvm.ptr>) -> !llvm.ptr> +# %31 = llvm.bitcast %30 : !llvm.ptr> to !llvm.ptr +# %32 = llvm.load %31 : !llvm.ptr +# %33 = llvm.zext %32 : i1 to i8 +# llvm.store %33, %26 : !llvm.ptr +# %34 = llvm.mlir.addressof @cstr.72303030303100 : !llvm.ptr> +# %35 = llvm.bitcast %34 : !llvm.ptr> to !llvm.ptr +# %36 = llvm.call @__quantum__qis__mz(%15) {registerName = "r00001", result.index = 1 : i64} : (!llvm.ptr>) -> !llvm.ptr> +# %37 = llvm.bitcast %36 : !llvm.ptr> to !llvm.ptr +# %38 = llvm.load %37 : !llvm.ptr +# %39 = llvm.zext %38 : i1 to i8 +# llvm.store %39, %27 : !llvm.ptr +# llvm.call @__quantum__rt__qubit_release_array(%1) : (!llvm.ptr>) -> () +# %40 = llvm.mlir.constant(0 : i64) : i64 +# %41 = llvm.inttoptr %40 : i64 to !llvm.ptr> +# %42 = llvm.mlir.addressof @cstr.72303030303000 : !llvm.ptr> +# %43 = llvm.bitcast %42 : !llvm.ptr> to !llvm.ptr +# llvm.call @__quantum__rt__result_record_output(%41, %43) : (!llvm.ptr>, !llvm.ptr) -> () +# %44 = llvm.mlir.constant(1 : i64) : i64 +# %45 = llvm.inttoptr %44 : i64 to !llvm.ptr> +# %46 = llvm.mlir.addressof @cstr.72303030303100 : !llvm.ptr> +# %47 = llvm.bitcast %46 : !llvm.ptr> to !llvm.ptr +# llvm.call @__quantum__rt__result_record_output(%45, %47) : (!llvm.ptr>, !llvm.ptr) -> () +# llvm.return +# } +# llvm.mlir.global private constant @cstr.72303030303000("r00000\00") {addr_space = 0 : i32} +# llvm.mlir.global private constant @cstr.72303030303100("r00001\00") {addr_space = 0 : i32} +# } \ No newline at end of file diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 5fd216c5b1..dd2632c49e 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -272,6 +272,22 @@ def kernel(qubit_count: int): assert "0000" in counts assert "1111" in counts +def test_kernel_subveqs(): + + @cudaq.kernel + def kernel(): + qreg = cudaq.qvector(4) + h(qreg[0]) + for qubit in range(3): + x.ctrl(qreg[qubit], qreg[qubit + 1]) + v = qreg[1:2] + mz(v) + + counts = cudaq.sample(kernel, 4, shots_count=100) + assert len(counts) == 2 + assert "0000" in counts + assert "1111" in counts + @pytest.mark.parametrize("device_arn", [ "arn:aws:braket:::device/quantum-simulator/amazon/dm1", diff --git a/runtime/common/BaseRemoteRESTQPU.h b/runtime/common/BaseRemoteRESTQPU.h index f8e67601d7..79d6116b00 100644 --- a/runtime/common/BaseRemoteRESTQPU.h +++ b/runtime/common/BaseRemoteRESTQPU.h @@ -21,6 +21,7 @@ #include "cudaq/Optimizer/Builder/Runtime.h" #include "cudaq/Optimizer/CodeGen/OpenQASMEmitter.h" #include "cudaq/Optimizer/CodeGen/Passes.h" +#include "cudaq/Optimizer/CodeGen/QIRAttributeNames.h" #include "cudaq/Optimizer/Dialect/CC/CCDialect.h" #include "cudaq/Optimizer/Dialect/CC/CCOps.h" #include "cudaq/Optimizer/Dialect/Quake/QuakeDialect.h" @@ -332,7 +333,7 @@ class BaseRemoteRESTQPU : public cudaq::QPU { } /// @brief Conditionally form an output_names JSON object if this was for QIR - nlohmann::json formOutputNames(const std::string &codegenTranslation, + nlohmann::json formOutputNames(const std::string &codegenTranslation, mlir::ModuleOp moduleOp, const std::string &codeStr) { // Form an output_names mapping from codeStr nlohmann::json output_names; @@ -359,6 +360,15 @@ class BaseRemoteRESTQPU : public cudaq::QPU { } } } + } else if (codegenTranslation.starts_with("qasm2")) { + for (auto &op : moduleOp) { + if (op.hasAttr(cudaq::entryPointAttrName) && op.hasAttr("output_names")) { + if (auto strAttr = op.getAttr(cudaq::opt::QIROutputNamesAttrName).dyn_cast_or_null()) { + output_names = nlohmann::json::parse(strAttr.getValue()); + break; + } + } + } } return output_names; } @@ -551,9 +561,12 @@ class BaseRemoteRESTQPU : public cudaq::QPU { throw std::runtime_error("Could not successfully translate to " + codegenTranslation + "."); } - + // TODO: see if modules are new here? + std::cout << "NEW MODULE: " << std::endl; + moduleOpI.dump(); + std::cout << "CODE STR: " << codeStr << std::endl; // Form an output_names mapping from codeStr - nlohmann::json j = formOutputNames(codegenTranslation, codeStr); + nlohmann::json j = formOutputNames(codegenTranslation, moduleOpI, codeStr); codes.emplace_back(name, codeStr, j, mapping_reorder_idx); } diff --git a/runtime/common/RuntimeMLIRCommonImpl.h b/runtime/common/RuntimeMLIRCommonImpl.h index e567b1f0a7..57d92b45ad 100644 --- a/runtime/common/RuntimeMLIRCommonImpl.h +++ b/runtime/common/RuntimeMLIRCommonImpl.h @@ -10,6 +10,7 @@ #include "Logger.h" #include "Timing.h" +#include "Environment.h" #include "cudaq/Frontend/nvqpp/AttributeNames.h" #include "cudaq/Optimizer/Builder/Runtime.h" #include "cudaq/Optimizer/CodeGen/IQMJsonEmitter.h" @@ -678,6 +679,13 @@ mlir::ExecutionEngine *createQIRJITEngine(mlir::ModuleOp &moduleOp, cudaq::opt::addWiresetToProfileQIRPipeline(pm, convertTo); else cudaq::opt::commonPipelineConvertToQIR(pm, convertTo); + + auto enablePrintMLIREachPass = + getEnvBool("CUDAQ_MLIR_PRINT_EACH_PASS", false); + if (enablePrintMLIREachPass) { + module->getContext()->disableMultithreading(); + pm.enableIRPrinting(); + } mlir::DefaultTimingManager tm; tm.setEnabled(cudaq::isTimingTagEnabled(cudaq::TIMING_JIT_PASSES)); diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp index d99549cf03..ba913dff93 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp @@ -20,6 +20,8 @@ #include +#include + namespace { void tryCreateBucket(Aws::S3Crt::S3CrtClient &client, std::string const ®ion, std::string const &bucketName) { @@ -162,95 +164,104 @@ ServerJobPayload BraketExecutor::checkHelperAndCreateJob( details::future BraketExecutor::execute(std::vector &codesToExecute) { - auto [dummy1, dummy2, messages] = checkHelperAndCreateJob(codesToExecute); + // auto [dummy1, dummy2, messages] = checkHelperAndCreateJob(codesToExecute); - std::string const defaultBucket = defaultBucketFuture.get(); - std::string const defaultPrefix = "tasks"; + // std::string const defaultBucket = defaultBucketFuture.get(); + // std::string const defaultPrefix = "tasks"; - std::vector - createOutcomes; + // std::vector + // createOutcomes; - for (const auto &message : messages) { - Aws::Braket::Model::CreateQuantumTaskRequest req; - req.SetAction(message["action"]); - req.SetDeviceArn(message["deviceArn"]); - req.SetShots(message["shots"]); - if (jobToken) - req.SetJobToken(jobToken); - req.SetOutputS3Bucket(defaultBucket); - req.SetOutputS3KeyPrefix(defaultPrefix); + // for (const auto &message : messages) { + // Aws::Braket::Model::CreateQuantumTaskRequest req; + // req.SetAction(message["action"]); + // req.SetDeviceArn(message["deviceArn"]); + // req.SetShots(message["shots"]); + // if (jobToken) + // req.SetJobToken(jobToken); + // req.SetOutputS3Bucket(defaultBucket); + // req.SetOutputS3KeyPrefix(defaultPrefix); - createOutcomes.push_back(braketClientPtr->CreateQuantumTaskCallable(req)); - } + // createOutcomes.push_back(braketClientPtr->CreateQuantumTaskCallable(req)); + // } return std::async( std::launch::async, - [this](std::vector - createOutcomes) { + [this](/*std::vector + createOutcomes*/) { std::vector results; - for (auto &outcome : createOutcomes) { - auto createResponse = outcome.get(); - if (!createResponse.IsSuccess()) { - throw std::runtime_error(createResponse.GetError().GetMessage()); - } - std::string taskArn = createResponse.GetResult().GetQuantumTaskArn(); - cudaq::info("Created Braket quantum task {}", taskArn); - - Aws::Braket::Model::GetQuantumTaskRequest req; - req.SetQuantumTaskArn(taskArn); - auto getResponse = braketClientPtr->GetQuantumTask(req); - if (!getResponse.IsSuccess()) { - throw std::runtime_error(getResponse.GetError().GetMessage()); - } - auto taskStatus = getResponse.GetResult().GetStatus(); - while ( - taskStatus != Aws::Braket::Model::QuantumTaskStatus::COMPLETED && - taskStatus != Aws::Braket::Model::QuantumTaskStatus::FAILED && - taskStatus != Aws::Braket::Model::QuantumTaskStatus::CANCELLED) { - std::this_thread::sleep_for(pollingInterval); - - getResponse = braketClientPtr->GetQuantumTask(req); - if (!getResponse.IsSuccess()) { - throw std::runtime_error(getResponse.GetError().GetMessage()); - } - taskStatus = getResponse.GetResult().GetStatus(); - } - - auto getResult = getResponse.GetResult(); - if (taskStatus != Aws::Braket::Model::QuantumTaskStatus::COMPLETED) { - // Task terminated without results - throw std::runtime_error( - fmt::format("Braket task {} terminated without results. {}", - taskArn, getResult.GetFailureReason())); - } - - std::string outBucket = getResult.GetOutputS3Bucket(); - std::string outPrefix = getResult.GetOutputS3Directory(); - - cudaq::info("Fetching braket quantum task {} results from " - "s3://{}/{}/results.json", - taskArn, outBucket, outPrefix); - - Aws::S3Crt::Model::GetObjectRequest resultsJsonRequest; - resultsJsonRequest.SetBucket(outBucket); - resultsJsonRequest.SetKey(fmt::format("{}/results.json", outPrefix)); - auto s3Response = s3ClientPtr->GetObject(resultsJsonRequest); - if (!s3Response.IsSuccess()) { - throw std::runtime_error(s3Response.GetError().GetMessage()); - } - auto resultsJson = nlohmann::json::parse( - s3Response.GetResultWithOwnership().GetBody()); + //for (auto &outcome : createOutcomes) { + // auto createResponse = outcome.get(); + // if (!createResponse.IsSuccess()) { + // throw std::runtime_error(createResponse.GetError().GetMessage()); + // } + // std::string taskArn = createResponse.GetResult().GetQuantumTaskArn(); + + // cudaq::info("Created Braket quantum task {}", taskArn); + + // Aws::Braket::Model::GetQuantumTaskRequest req; + // req.SetQuantumTaskArn(taskArn); + // auto getResponse = braketClientPtr->GetQuantumTask(req); + // if (!getResponse.IsSuccess()) { + // throw std::runtime_error(getResponse.GetError().GetMessage()); + // } + // auto taskStatus = getResponse.GetResult().GetStatus(); + // while ( + // taskStatus != Aws::Braket::Model::QuantumTaskStatus::COMPLETED && + // taskStatus != Aws::Braket::Model::QuantumTaskStatus::FAILED && + // taskStatus != Aws::Braket::Model::QuantumTaskStatus::CANCELLED) { + // std::this_thread::sleep_for(pollingInterval); + + // getResponse = braketClientPtr->GetQuantumTask(req); + // if (!getResponse.IsSuccess()) { + // throw std::runtime_error(getResponse.GetError().GetMessage()); + // } + // taskStatus = getResponse.GetResult().GetStatus(); + // } + + // auto getResult = getResponse.GetResult(); + // if (taskStatus != Aws::Braket::Model::QuantumTaskStatus::COMPLETED) { + // // Task terminated without results + // throw std::runtime_error( + // fmt::format("Braket task {} terminated without results. {}", + // taskArn, getResult.GetFailureReason())); + // } + + // std::string outBucket = getResult.GetOutputS3Bucket(); + // std::string outPrefix = getResult.GetOutputS3Directory(); + + // cudaq::info("Fetching braket quantum task {} results from " + // "s3://{}/{}/results.json", + // taskArn, outBucket, outPrefix); + + // Aws::S3Crt::Model::GetObjectRequest resultsJsonRequest; + // resultsJsonRequest.SetBucket(outBucket); + // resultsJsonRequest.SetKey(fmt::format("{}/results.json", outPrefix)); + // auto s3Response = s3ClientPtr->GetObject(resultsJsonRequest); + // if (!s3Response.IsSuccess()) { + // throw std::runtime_error(s3Response.GetError().GetMessage()); + // } + // auto resultsJson = nlohmann::json::parse( + // s3Response.GetResultWithOwnership().GetBody()); + std::string taskArn = "arn:aws:braket:us-east-1:783764578061:quantum-task/8bad9d49-b546-4ed8-8517-1b23c1eb929e"; + auto resultsJson = nlohmann::json::parse("{\"additionalMetadata\":{\"action\":{\"braketSchemaHeader\":{\"name\":\"braket.ir.openqasm.program\",\"version\":\"1\"},\"inputs\":{},\"source\":\"// Code generated by NVIDIA's nvq++ compiler\\nOPENQASM 2.0;\\n\\n\\n\\nqreg var0[4];\\nx var0[1];\\nx var0[2];\\ncreg var3[4];\\nmeasure var0 -> var3;\\n\"},\"simulatorMetadata\":{\"braketSchemaHeader\":{\"name\":\"braket.task_result.simulator_metadata\",\"version\":\"1\"},\"executionDuration\":2}},\"braketSchemaHeader\":{\"name\":\"braket.task_result.gate_model_task_result\",\"version\":\"1\"},\"measuredQubits\":[0,1,2,3],\"measurements\":[[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0]],\"resultTypes\":[],\"taskMetadata\":{\"braketSchemaHeader\":{\"name\":\"braket.task_result.task_metadata\",\"version\":\"1\"},\"createdAt\":\"2024-11-23T19:16:08.872Z\",\"deviceId\":\"arn:aws:braket:::device/quantum-simulator/amazon/sv1\",\"deviceParameters\":{\"braketSchemaHeader\":{\"name\":\"braket.device_schema.simulators.gate_model_simulator_device_parameters\",\"version\":\"1\"},\"paradigmParameters\":{\"braketSchemaHeader\":{\"name\":\"braket.device_schema.gate_model_parameters\",\"version\":\"1\"},\"disableQubitRewiring\":false,\"qubitCount\":4}},\"endedAt\":\"2024-11-23T19:16:10.138Z\",\"id\":\"arn:aws:braket:us-east-1:783764578061:quantum-task/8bad9d49-b546-4ed8-8517-1b23c1eb929e\",\"shots\":100,\"status\":\"COMPLETED\"}}"); + std::cout << "Results: " << resultsJson << std::endl; auto c = serverHelper->processResults(resultsJson, taskArn); for (auto ®Name : c.register_names()) { + std::cout << "Register name: " << regName << std::endl; results.emplace_back(c.to_map(regName), regName); + std::cout << "Sequential data: " << regName << std::endl; + for(auto d: c.sequential_data(regName)) { + std::cout << d << std::endl; + } results.back().sequentialData = c.sequential_data(regName); } - } + //} return sample_result(results); - }, - std::move(createOutcomes)); + }/*, + std::move(createOutcomes)*/); } } // namespace cudaq diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp index 26ba0ceb42..e709846ac1 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp @@ -7,6 +7,7 @@ ******************************************************************************/ #include "common/BraketServerHelper.h" +#include namespace { std::string prepareOpenQasm(std::string source) { @@ -113,7 +114,22 @@ BraketServerHelper::createJob(std::vector &circuitCodes) { }; sample_result BraketServerHelper::processResults(ServerMessage &resultsJson, - std::string &) { + std::string &jobID) { + + //if (outputNames.find(jobID) == outputNames.end()) + // throw std::runtime_error("Could not find output names for job " + jobID); + + //auto &output_names = outputNames[jobID]; + // Fake output names + cudaq::OutputNamesType output_names; + output_names[0] = cudaq::ResultInfoType{1, "1"}; + output_names[1] = cudaq::ResultInfoType{2, "2"}; + + for (auto &[result, info] : output_names) { + cudaq::info("Qubit {} Result {} Name {}", info.qubitNum, result, + info.registerName); + } + CountsDictionary counts; if (resultsJson.contains("measurements")) { @@ -136,7 +152,73 @@ sample_result BraketServerHelper::processResults(ServerMessage &resultsJson, } } - return sample_result{ExecutionResult{counts}}; + std::cout << "COUNTS: " << std::endl; + for (auto c: counts) { + std::cout << c.first << ": " << c.second < execResults; + + // Get a reduced list of qubit numbers that were in the original program + // so that we can slice the output data and extract the bits that the user + // was interested in. Sort by QIR qubit number. + std::vector qubitNumbers; + qubitNumbers.reserve(output_names.size()); + for (auto &[result, info] : output_names) { + qubitNumbers.push_back(info.qubitNum); + } + + // For each original counts entry in the full sample results, reduce it + // down to the user component and add to userGlobal. If qubitNumbers is empty, + // that means all qubits were measured. + if (qubitNumbers.empty()) { + execResults.emplace_back(ExecutionResult{fullSampleResults.to_map()}); + } else { + auto subset = fullSampleResults.get_marginal(qubitNumbers); + execResults.emplace_back(ExecutionResult{subset.to_map()}); + } + + // // Now add to `execResults` one register at a time + // for (const auto &[result, info] : output_names) { + // CountsDictionary regCounts; + // for (const auto &[bits, count] : fullSampleResults) + // regCounts[std::string{bits[info.qubitNum]}] += count; + // execResults.emplace_back(regCounts, info.registerName); + // } + + // Return a sample result including the global register and all individual + // registers. + auto ret = cudaq::sample_result(execResults); + return ret; + + //return sample_result{ExecutionResult{counts}}; } } // namespace cudaq diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 10a4072c22..db5baa7dcc 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -20,6 +20,8 @@ config: platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0},expand-control-veqs,canonicalize,combine-quantum-alloc),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 + # Additional passes to run after lowering to QUAKE + #post-codegen-passes: "remove-measurements" # Library mode is only for simulators, physical backends must turn this off library-mode: false diff --git a/tmp.qke b/tmp.qke new file mode 100644 index 0000000000..490f965031 --- /dev/null +++ b/tmp.qke @@ -0,0 +1,17 @@ +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %c1_i64 = arith.constant 1 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[0] : (!quake.veq<4>) -> !quake.ref + quake.h %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x [%1] %2 : (!quake.ref, !quake.ref) -> () + %3 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x [%2] %3 : (!quake.ref, !quake.ref) -> () + %4 = quake.extract_ref %0[3] : (!quake.veq<4>) -> !quake.ref + quake.x [%3] %4 : (!quake.ref, !quake.ref) -> () + %5 = quake.subveq %0, %c1_i64, %c1_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<1> + %measOut = quake.mz %5 : (!quake.veq<1>) -> !cc.stdvec + return + } +} \ No newline at end of file diff --git a/tmp.txt b/tmp.txt new file mode 100644 index 0000000000..80928883a5 --- /dev/null +++ b/tmp.txt @@ -0,0 +1,970 @@ +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:205] Init infrastructure for pythonic builder. +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target anyon with config file anyon.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: anyon -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target braket with config file braket.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: braket -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target density-matrix-cpu with config file density-matrix-cpu.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use dm simulator for target density-matrix-cpu +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: density-matrix-cpu -> (sim=dm, platform=default) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target fermioniq with config file fermioniq.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: fermioniq -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target ionq with config file ionq.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: ionq -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target iqm with config file iqm.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: iqm -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia-fp64 with config file nvidia-fp64.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp64 simulator for target nvidia-fp64 since it is not available +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp64 simulator for target nvidia-fp64 +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia-fp64 -> (sim=custatevec_fp64, platform=default) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia-mqpu-fp64 with config file nvidia-mqpu-fp64.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp64 simulator for target nvidia-mqpu-fp64 since it is not available +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp64 simulator for target nvidia-mqpu-fp64 +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia-mqpu-fp64 -> (sim=custatevec_fp64, platform=mqpu) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia-mqpu-mps with config file nvidia-mqpu-mps.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use tensornet-mps simulator for target nvidia-mqpu-mps +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia-mqpu-mps -> (sim=tensornet_mps, platform=mqpu) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia-mqpu with config file nvidia-mqpu.yml +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp32 simulator for target nvidia-mqpu since it is not available +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp32 simulator for target nvidia-mqpu +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia-mqpu -> (sim=custatevec_fp32, platform=mqpu) +[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia with config file nvidia.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp32 simulator for target nvidia since it is not available +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp32 simulator for target nvidia +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia -> (sim=custatevec_fp32, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target nvqc with config file nvqc.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvqc -> (sim=qpp, platform=mqpu) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target opt-test with config file opt-test.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp32 simulator for target opt-test since it is not available +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp32 simulator for target opt-test +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: opt-test -> (sim=custatevec_fp32, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target oqc with config file oqc.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: oqc -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target orca-photonics with config file orca-photonics.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: orca-photonics -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target orca with config file orca.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: orca -> (sim=qpp, platform=mqpu) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target qpp-cpu with config file qpp-cpu.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use qpp simulator for target qpp-cpu +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: qpp-cpu -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target quantinuum with config file quantinuum.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: quantinuum -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target quera with config file quera.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: quera -> (sim=qpp, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target remote-mqpu with config file remote-mqpu.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: remote-mqpu -> (sim=qpp, platform=mqpu) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target stim with config file stim.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use stim simulator for target stim +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: stim -> (sim=stim, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target tensornet-mps with config file tensornet-mps.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use tensornet-mps simulator for target tensornet-mps +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: tensornet-mps -> (sim=tensornet_mps, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target tensornet with config file tensornet.yml +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use tensornet simulator for target tensornet +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: tensornet -> (sim=tensornet, platform=default) +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:230] Init: Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:322] Found platform plugin default. +[2024-11-24 19:46:56.081] [info] [LinkedLibraryHolder.cpp:322] Found platform plugin mqpu. +[2024-11-24 19:46:56.094] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin custatevec_fp32. +[2024-11-24 19:46:56.094] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin custatevec_fp64. +[2024-11-24 19:46:56.094] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin custatevec_kernels. +[2024-11-24 19:46:56.095] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin dm. +[2024-11-24 19:46:56.095] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin qpp. +[2024-11-24 19:46:56.095] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin stim. +[2024-11-24 19:46:56.099] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin tensornet_mps. +[2024-11-24 19:46:56.099] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin tensornet. +[2024-11-24 19:46:56.160] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.160] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp32 simulator for target nvidia since it is not available +[2024-11-24 19:46:56.160] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. +[2024-11-24 19:46:56.160] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp32 simulator for target nvidia +[2024-11-24 19:46:56.161] [info] [LinkedLibraryHolder.cpp:455] Setting target=nvidia (sim=custatevec_fp32, platform=default) +[2024-11-24 19:46:56.161] [info] [PluginUtils.h:24] Requesting N5nvqir16CircuitSimulatorE plugin via symbol name getCircuitSimulator_custatevec_fp32. +[2024-11-24 19:46:56.161] [info] [PluginUtils.h:36] Successfully loaded the plugin. +[2024-11-24 19:46:56.310] [info] [NVQIR.cpp:70] [runtime] Setting the circuit simulator to custatevec-fp32. +[2024-11-24 19:46:56.310] [info] [PluginUtils.h:24] Requesting N5cudaq16quantum_platformE plugin via symbol name getQuantumPlatform_default. +[2024-11-24 19:46:56.310] [info] [PluginUtils.h:36] Successfully loaded the plugin. +[2024-11-24 19:46:56.310] [info] [DefaultQuantumPlatform.cpp:87] Backend string is nvidia +[2024-11-24 19:46:56.310] [info] [DefaultQuantumPlatform.cpp:104] Config file path = /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../targets/nvidia.yml +[2024-11-24 19:46:56.311] [info] [quantum_platform.cpp:37] external caller setting the platform. +[2024-11-24 19:46:56.311] [info] [execution_manager.cpp:21] external caller clearing the execution manager. +[2024-11-24 19:46:56.405] [info] [CUDAQuantumExtension.cpp:67] Calling initialize_cudaq. +[2024-11-24 19:46:56.405] [info] [LinkedLibraryHolder.cpp:455] Setting target=braket (sim=qpp, platform=default) +[2024-11-24 19:46:56.405] [info] [PluginUtils.h:24] Requesting N5nvqir16CircuitSimulatorE plugin via symbol name getCircuitSimulator_qpp. +[2024-11-24 19:46:56.405] [info] [PluginUtils.h:36] Successfully loaded the plugin. +[2024-11-24 19:46:56.405] [info] [NVQIR.cpp:70] [runtime] Setting the circuit simulator to qpp. +[2024-11-24 19:46:56.405] [info] [PluginUtils.h:24] Requesting N5cudaq16quantum_platformE plugin via symbol name getQuantumPlatform_default. +[2024-11-24 19:46:56.405] [info] [PluginUtils.h:36] Successfully loaded the plugin. +[2024-11-24 19:46:56.416] [info] [DefaultQuantumPlatform.cpp:87] Backend string is braket;machine;arn:aws:braket:::device/quantum-simulator/amazon/sv1 +[2024-11-24 19:46:56.416] [info] [DefaultQuantumPlatform.cpp:104] Config file path = /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../targets/braket.yml +[2024-11-24 19:46:56.416] [info] [DefaultQuantumPlatform.cpp:122] Default platform QPU subtype name: remote_rest +[2024-11-24 19:46:56.416] [info] [BaseRemoteRESTQPU.h:212] Remote REST platform is targeting braket;machine;arn:aws:braket:::device/quantum-simulator/amazon/sv1. +[2024-11-24 19:46:56.416] [info] [BaseRemoteRESTQPU.h:269] Config file path = /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../targets/braket.yml +[2024-11-24 19:46:56.416] [info] [BaseRemoteRESTQPU.h:279] Appending lowering pipeline: func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0},expand-control-veqs,canonicalize,combine-quantum-alloc),symbol-dce +[2024-11-24 19:46:56.417] [info] [BaseRemoteRESTQPU.h:285] Set codegen translation: qasm2 +[2024-11-24 19:46:56.417] [info] [BraketServerHelper.cpp:54] Initializing Amazon Braket backend. +[2024-11-24 19:46:56.417] [info] [BraketServerHelper.cpp:60] Running on device arn:aws:braket:::device/quantum-simulator/amazon/sv1 +[2024-11-24 19:46:56.417] [info] [BaseRemoteRESTQPU.h:324] Retrieving executor with name braket +[2024-11-24 19:46:56.417] [info] [BaseRemoteRESTQPU.h:326] Is this executor registered? true +[2024-11-24 19:46:56.438] [info] [quantum_platform.cpp:37] external caller setting the platform. +[2024-11-24 19:46:56.438] [info] [execution_manager.cpp:21] external caller clearing the execution manager. +[2024-11-24 19:46:56.438] [info] [BaseRemoteRESTQPU.h:195] Remote Rest QPU setting execution context to sample +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} +[2024-11-24 19:46:56.465] [info] [BaseRemoteRESTQPU.h:602] launching remote rest kernel (kernel) +[2024-11-24 19:46:56.466] [info] [cudaq.cpp:220] Replacing code for kernel kernel +[2024-11-24 19:46:56.466] [info] [BaseRemoteRESTQPU.h:430] Pass pipeline for kernel = cc-loop-unroll{allow-early-exit=0},canonicalize,func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0},expand-control-veqs,canonicalize,combine-quantum-alloc),symbol-dce +// -----// IR Dump Before LoopUnroll (cc-loop-unroll) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before ConstPropComplex (const-prop-complex) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before CSE (cse) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before LiftArrayAlloc (lift-array-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before GlobalizeArrayValues (globalize-array-values) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before StatePreparation (state-prep) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before UnitarySynthesis (unitary-synthesis) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before ApplySpecialization (apply-op-specialization) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before ConvertToDirectCalls (indirect-to-direct-calls) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Inliner (inline) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before CheckKernelCalls (check-kernel-calls) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before MemToReg (memtoreg) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before LoopNormalize (cc-loop-normalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before LoopUnroll (cc-loop-unroll) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before UpdateRegisterNames (update-register-names) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before LowerToCFG (lower-to-cfg) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before MultiControlDecompositionPass (multicontrol-decomposition) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before DecompositionPass (decomposition) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before MemToReg (memtoreg) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before ExpandControlVeqs (expand-control-veqs) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before CombineQuantumAllocations (combine-quantum-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump After CombineQuantumAllocations (combine-quantum-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %c0_i64 = arith.constant 0 : i64 + %c3_i64 = arith.constant 3 : i64 + %c2_i64 = arith.constant 2 : i64 + %c1_i64 = arith.constant 1 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> + %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %3 : (!quake.ref) -> () + %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before SymbolDCE (symbol-dce) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %c0_i64 = arith.constant 0 : i64 + %c3_i64 = arith.constant 3 : i64 + %c2_i64 = arith.constant 2 : i64 + %c1_i64 = arith.constant 1 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> + %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %3 : (!quake.ref) -> () + %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %c0_i64 = arith.constant 0 : i64 + %c3_i64 = arith.constant 3 : i64 + %c2_i64 = arith.constant 2 : i64 + %c1_i64 = arith.constant 1 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> + %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %3 : (!quake.ref) -> () + %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump After Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before CSE (cse) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before MemToReg (memtoreg) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before LoopUnroll (cc-loop-unroll) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before LiftArrayAlloc (lift-array-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before GlobalizeArrayValues (globalize-array-values) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before StatePreparation (state-prep) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before GetConcreteMatrix (get-concrete-matrix) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before UnitarySynthesis (unitary-synthesis) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before SymbolDCE (symbol-dce) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before CSE (cse) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before MultiControlDecompositionPass (multicontrol-decomposition) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before DecompositionPass (decomposition) ('builtin.module' operation) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before ExpandControlVeqs (expand-control-veqs) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before CombineQuantumAllocations (combine-quantum-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump After CombineQuantumAllocations (combine-quantum-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %c0_i64 = arith.constant 0 : i64 + %c3_i64 = arith.constant 3 : i64 + %c2_i64 = arith.constant 2 : i64 + %c1_i64 = arith.constant 1 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> + %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %3 : (!quake.ref) -> () + %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before CombineMeasurements (combine-measurements) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { + %c0_i64 = arith.constant 0 : i64 + %c3_i64 = arith.constant 3 : i64 + %c2_i64 = arith.constant 2 : i64 + %c1_i64 = arith.constant 1 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> + %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %3 : (!quake.ref) -> () + %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump After CombineMeasurements (combine-measurements) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", output_names = "[[[0,[0,\220\22]],[1,[1,\221\22]],[2,[2,\222\22]]]]"} { + %c2_i64 = arith.constant 2 : i64 + %c1_i64 = arith.constant 1 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump Before Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", output_names = "[[[0,[0,\220\22]],[1,[1,\221\22]],[2,[2,\222\22]]]]"} { + %c2_i64 = arith.constant 2 : i64 + %c1_i64 = arith.constant 1 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +// -----// IR Dump After Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", output_names = "[[[0,[0,\220\22]],[1,[1,\221\22]],[2,[2,\222\22]]]]"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} + + +NEW MODULE: +module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { + func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", output_names = "[[[0,[0,\220\22]],[1,[1,\221\22]],[2,[2,\222\22]]]]"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + quake.x %1 : (!quake.ref) -> () + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + quake.x %2 : (!quake.ref) -> () + %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec + return + } +} +CODE STR: // Code generated by NVIDIA's nvq++ compiler +OPENQASM 2.0; + +include "qelib1.inc"; + +qreg var0[4]; +x var0[1]; +x var0[2]; +creg var3[4]; +measure var0 -> var3; + +Results: {"additionalMetadata":{"action":{"braketSchemaHeader":{"name":"braket.ir.openqasm.program","version":"1"},"inputs":{},"source":"// Code generated by NVIDIA's nvq++ compiler\nOPENQASM 2.0;\n\n\n\nqreg var0[4];\nx var0[1];\nx var0[2];\ncreg var3[4];\nmeasure var0 -> var3;\n"},"simulatorMetadata":{"braketSchemaHeader":{"name":"braket.task_result.simulator_metadata","version":"1"},"executionDuration":2}},"braketSchemaHeader":{"name":"braket.task_result.gate_model_task_result","version":"1"},"measuredQubits":[0,1,2,3],"measurements":[[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0]],"resultTypes":[],"taskMetadata":{"braketSchemaHeader":{"name":"braket.task_result.task_metadata","version":"1"},"createdAt":"2024-11-23T19:16:08.872Z","deviceId":"arn:aws:braket:::device/quantum-simulator/amazon/sv1","deviceParameters":{"braketSchemaHeader":{"name":"braket.device_schema.simulators.gate_model_simulator_device_parameters","version":"1"},"paradigmParameters":{"braketSchemaHeader":{"name":"braket.device_schema.gate_model_parameters","version":"1"},"disableQubitRewiring":false,"qubitCount":4}},"endedAt":"2024-11-23T19:16:10.138Z","id":"arn:aws:braket:us-east-1:783764578061:quantum-task/8bad9d49-b546-4ed8-8517-1b23c1eb929e","shots":100,"status":"COMPLETED"}} +[2024-11-24 19:46:56.483] [info] [BraketServerHelper.cpp:130] Qubit 1 Result 0 Name q1 +[2024-11-24 19:46:56.483] [info] [BraketServerHelper.cpp:130] Qubit 2 Result 1 Name q2 +COUNTS: +0110: 100 +Register name: __global__ +Sequential data: __global__ +{ 11:100 } + From db0b361f5c1e295b86acb803079234b920591c7b Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Sun, 24 Nov 2024 22:52:09 -0800 Subject: [PATCH 31/47] * Remove the decomposition patterns for 'SAdjToSZ' and 'TAdjToR1' since the existing 'SToR1' and 'TToR1' are sufficient * Disable 'R1toU3' pattern on all pipelines * Clean -up comments Signed-off-by: Pradnya Khalate --- lib/Optimizer/CodeGen/Passes.cpp | 7 +++ lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp | 2 +- .../Transforms/DecompositionPatterns.cpp | 58 ------------------- python/runtime/utils/PyRemoteRESTQPU.cpp | 3 - .../default/rest/helpers/braket/braket.yml | 2 +- .../BasisConversion/phased_rx-cz.qke | 4 +- test/Translate/openqasm2_adj_rotations.cpp | 8 ++- 7 files changed, 16 insertions(+), 68 deletions(-) diff --git a/lib/Optimizer/CodeGen/Passes.cpp b/lib/Optimizer/CodeGen/Passes.cpp index 5b44d65391..1587e814b7 100644 --- a/lib/Optimizer/CodeGen/Passes.cpp +++ b/lib/Optimizer/CodeGen/Passes.cpp @@ -21,6 +21,7 @@ static void addAnyonPPipeline(OpPassManager &pm) { }; BasisConversionPassOptions options; options.basis = basis; + options.disabledPatterns = {"R1ToU3"}; pm.addPass(createBasisConversionPass(options)); } @@ -31,6 +32,7 @@ static void addAnyonCPipeline(OpPassManager &pm) { }; BasisConversionPassOptions options; options.basis = basis; + options.disabledPatterns = {"R1ToU3"}; pm.addPass(createBasisConversionPass(options)); } @@ -42,6 +44,7 @@ static void addOQCPipeline(OpPassManager &pm) { }; BasisConversionPassOptions options; options.basis = basis; + options.disabledPatterns = {"R1ToU3"}; pm.addPass(createBasisConversionPass(options)); } @@ -52,6 +55,7 @@ static void addQuantinuumPipeline(OpPassManager &pm) { }; BasisConversionPassOptions options; options.basis = basis; + options.disabledPatterns = {"R1ToU3"}; pm.addPass(createBasisConversionPass(options)); } @@ -63,6 +67,7 @@ static void addIQMPipeline(OpPassManager &pm) { }; BasisConversionPassOptions options; options.basis = basis; + options.disabledPatterns = {"R1ToU3"}; pm.addPass(createBasisConversionPass(options)); } @@ -74,6 +79,7 @@ static void addIonQPipeline(OpPassManager &pm) { }; BasisConversionPassOptions options; options.basis = basis; + options.disabledPatterns = {"R1ToU3"}; pm.addPass(createBasisConversionPass(options)); } @@ -84,6 +90,7 @@ static void addFermioniqPipeline(OpPassManager &pm) { }; BasisConversionPassOptions options; options.basis = basis; + options.disabledPatterns = {"R1ToU3"}; pm.addPass(createBasisConversionPass(options)); } diff --git a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp index 631118a2c5..5c112567e2 100644 --- a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp +++ b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp @@ -23,7 +23,7 @@ using namespace cudaq; //===----------------------------------------------------------------------===// // Helper functions //===----------------------------------------------------------------------===// -/// FIXME: Remove this code, move logic to decomposition patterns +/// FIXME: Re-evaluate this renaming workflow; consider using decomposition /// Translates operation names into OpenQASM gate names static LogicalResult translateOperatorName(quake::OperatorInterface optor, StringRef &name) { diff --git a/lib/Optimizer/Transforms/DecompositionPatterns.cpp b/lib/Optimizer/Transforms/DecompositionPatterns.cpp index 845b07093f..ca299f0367 100644 --- a/lib/Optimizer/Transforms/DecompositionPatterns.cpp +++ b/lib/Optimizer/Transforms/DecompositionPatterns.cpp @@ -622,35 +622,6 @@ struct SToR1 : public OpRewritePattern { } }; -// quake.s [control] target -// ───────────────────────────────── -// quake.z [control] target -// quake.s [control] target -struct SAdjToSZ : public OpRewritePattern { - using OpRewritePattern::OpRewritePattern; - - void initialize() { setDebugName("SAdjToSZ"); } - - LogicalResult matchAndRewrite(quake::SOp op, - PatternRewriter &rewriter) const override { - if (!op.isAdj()) - return failure(); - - // Op info - auto loc = op->getLoc(); - auto parameters = op.getParameters(); - SmallVector controls(op.getControls()); - Value target = op.getTarget(); - - QuakeOperatorCreator qRewriter(rewriter); - qRewriter.create(loc, parameters, controls, target); - qRewriter.create(loc, parameters, controls, target); - qRewriter.selectWiresAndReplaceUses(op, controls, target); - rewriter.eraseOp(op); - return success(); - } -}; - //===----------------------------------------------------------------------===// // TOp decompositions //===----------------------------------------------------------------------===// @@ -727,33 +698,6 @@ struct TToR1 : public OpRewritePattern { } }; -// quake.tdg [control] target -// ──────────────────────────────────── -// quake.r1(-π/4) [control] target -struct TAdjToR1 : public OpRewritePattern { - using OpRewritePattern::OpRewritePattern; - - void initialize() { setDebugName("TAdjToR1"); } - - LogicalResult matchAndRewrite(quake::TOp op, - PatternRewriter &rewriter) const override { - if (!op.isAdj()) - return failure(); - - // Op info - auto loc = op->getLoc(); - SmallVector controls(op.getControls()); - Value target = op.getTarget(); - - QuakeOperatorCreator qRewriter(rewriter); - Value angle = createConstant(loc, -M_PI_4, rewriter.getF64Type(), rewriter); - qRewriter.create(loc, angle, controls, target); - qRewriter.selectWiresAndReplaceUses(op, controls, target); - rewriter.eraseOp(op); - return success(); - } -}; - //===----------------------------------------------------------------------===// // XOp decompositions //===----------------------------------------------------------------------===// @@ -1612,11 +1556,9 @@ void cudaq::populateWithAllDecompositionPatterns(RewritePatternSet &patterns) { // SOp patterns SToPhasedRx, SToR1, - SAdjToSZ, // TOp patterns TToPhasedRx, TToR1, - TAdjToR1, // XOp patterns CXToCZ, CCXToCCZ, diff --git a/python/runtime/utils/PyRemoteRESTQPU.cpp b/python/runtime/utils/PyRemoteRESTQPU.cpp index 58dca879df..866b9492be 100644 --- a/python/runtime/utils/PyRemoteRESTQPU.cpp +++ b/python/runtime/utils/PyRemoteRESTQPU.cpp @@ -89,9 +89,6 @@ class PyRemoteRESTQPU : public cudaq::BaseRemoteRESTQPU { pm.addPass(mlir::createCanonicalizerPass()); pm.addPass(cudaq::opt::createApplyOpSpecializationPass()); pm.addPass(createInlinerPass()); - /// NOTE: This change is for the `braket` target. May require additional - /// pass in other pipelines. - // pm.addPass(cudaq::opt::createExpandMeasurementsPass()); pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); if (failed(pm.run(cloned))) diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 519d81d4ea..f4c09d7260 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=SToR1,TToR1,SAdjToSZ,TAdjToR1,R1ToU3,U3ToRotations,CHToCX,CCZToCX,CRzToCX,CRyToCX,CRxToCX,CR1ToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=SToR1,TToR1,R1ToU3,U3ToRotations,CHToCX,CCZToCX,CRzToCX,CRyToCX,CRxToCX,CR1ToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(memtoreg{quantum=0}),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Library mode is only for simulators, physical backends must turn this off diff --git a/test/Transforms/BasisConversion/phased_rx-cz.qke b/test/Transforms/BasisConversion/phased_rx-cz.qke index daaca01a0f..922a65ed90 100644 --- a/test/Transforms/BasisConversion/phased_rx-cz.qke +++ b/test/Transforms/BasisConversion/phased_rx-cz.qke @@ -6,8 +6,8 @@ // the terms of the Apache License 2.0 which accompanies this distribution. // // ========================================================================== // -// RUN: cudaq-opt -pass-pipeline='builtin.module(basis-conversion{basis=z(1),phased_rx})' %s | FileCheck %s -// RUN: cudaq-opt -pass-pipeline='builtin.module(basis-conversion{basis=z(1),phased_rx})' %s | CircuitCheck %s --up-to-global-phase +// RUN: cudaq-opt -pass-pipeline='builtin.module(basis-conversion{basis=z(1),phased_rx,disable-patterns=R1ToU3})' %s | FileCheck %s +// RUN: cudaq-opt -pass-pipeline='builtin.module(basis-conversion{basis=z(1),phased_rx,disable-patterns=R1ToU3})' %s | CircuitCheck %s --up-to-global-phase // CHECK-LABEL: func.func @cx diff --git a/test/Translate/openqasm2_adj_rotations.cpp b/test/Translate/openqasm2_adj_rotations.cpp index b9cbb2bac6..67e6996689 100644 --- a/test/Translate/openqasm2_adj_rotations.cpp +++ b/test/Translate/openqasm2_adj_rotations.cpp @@ -39,6 +39,8 @@ int main() { counts.dump(); } +/// FIXME - See comment in `translateOperatorName`. `h` --> `ch` skipped + // CHECK: // Code generated by NVIDIA's nvq++ compiler // CHECK: OPENQASM 2.0; @@ -49,13 +51,13 @@ int main() { // CHECK: qreg var0[6]; // CHECK: x var0[5]; -// CHECK: ch var0[4], var0[5]; +// CHECK: h var0[4], var0[5]; // CHECK: rx(-6.700000e-01) var0[4]; // CHECK: x var0[3]; -// CHECK: ch var0[2], var0[3]; +// CHECK: h var0[2], var0[3]; // CHECK: ry(-6.700000e-01) var0[2]; // CHECK: x var0[1]; -// CHECK: ch var0[0], var0[1]; +// CHECK: h var0[0], var0[1]; // CHECK: rz(-6.700000e-01) var0[0]; // CHECK: creg var7[6]; // CHECK: measure var0 -> var7; From 258e0e9175c1f3dd613aadb648b527970945913d Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Mon, 25 Nov 2024 10:25:04 -0800 Subject: [PATCH 32/47] * Restore 'translateOperatorName' function, and the corresponding test Signed-off-by: Pradnya Khalate --- lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp | 8 ++++++-- test/Translate/openqasm2_adj_rotations.cpp | 8 +++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp index 5c112567e2..391eeb1f2e 100644 --- a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp +++ b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp @@ -23,18 +23,22 @@ using namespace cudaq; //===----------------------------------------------------------------------===// // Helper functions //===----------------------------------------------------------------------===// -/// FIXME: Re-evaluate this renaming workflow; consider using decomposition /// Translates operation names into OpenQASM gate names static LogicalResult translateOperatorName(quake::OperatorInterface optor, StringRef &name) { StringRef qkeName = optor->getName().stripDialect(); if (optor.getControls().size() == 0) { - name = StringSwitch(qkeName).Default(qkeName); + name = StringSwitch(qkeName).Case("r1", "u1").Default(qkeName); } else if (optor.getControls().size() == 1) { name = StringSwitch(qkeName) + .Case("h", "ch") .Case("x", "cx") .Case("y", "cy") .Case("z", "cz") + .Case("r1", "cu1") + .Case("rx", "crx") + .Case("ry", "cry") + .Case("rz", "crz") .Case("swap", "cswap") .Default(qkeName); } else if (optor.getControls().size() == 2) { diff --git a/test/Translate/openqasm2_adj_rotations.cpp b/test/Translate/openqasm2_adj_rotations.cpp index 67e6996689..b9cbb2bac6 100644 --- a/test/Translate/openqasm2_adj_rotations.cpp +++ b/test/Translate/openqasm2_adj_rotations.cpp @@ -39,8 +39,6 @@ int main() { counts.dump(); } -/// FIXME - See comment in `translateOperatorName`. `h` --> `ch` skipped - // CHECK: // Code generated by NVIDIA's nvq++ compiler // CHECK: OPENQASM 2.0; @@ -51,13 +49,13 @@ int main() { // CHECK: qreg var0[6]; // CHECK: x var0[5]; -// CHECK: h var0[4], var0[5]; +// CHECK: ch var0[4], var0[5]; // CHECK: rx(-6.700000e-01) var0[4]; // CHECK: x var0[3]; -// CHECK: h var0[2], var0[3]; +// CHECK: ch var0[2], var0[3]; // CHECK: ry(-6.700000e-01) var0[2]; // CHECK: x var0[1]; -// CHECK: h var0[0], var0[1]; +// CHECK: ch var0[0], var0[1]; // CHECK: rz(-6.700000e-01) var0[0]; // CHECK: creg var7[6]; // CHECK: measure var0 -> var7; From e33f2a8754ca75c18761499ffa1c22838bdac8d5 Mon Sep 17 00:00:00 2001 From: Pradnya Khalate Date: Mon, 25 Nov 2024 12:35:19 -0800 Subject: [PATCH 33/47] * Correct the comment about global pahse on R1ToU3 * Simpler command-line invocation in test Signed-off-by: Pradnya Khalate --- lib/Optimizer/Transforms/DecompositionPatterns.cpp | 2 +- test/Transforms/BasisConversion/phased_rx-cz.qke | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Optimizer/Transforms/DecompositionPatterns.cpp b/lib/Optimizer/Transforms/DecompositionPatterns.cpp index ca299f0367..988ba346b9 100644 --- a/lib/Optimizer/Transforms/DecompositionPatterns.cpp +++ b/lib/Optimizer/Transforms/DecompositionPatterns.cpp @@ -460,7 +460,7 @@ struct R1ToRz : public OpRewritePattern { } }; -// Naive mapping of R1 to U3, ignoring the global phase. +// Naive mapping of R1 to U3 // This is only expected to work with full inlining and // quake apply specialization. struct R1ToU3 : public OpRewritePattern { diff --git a/test/Transforms/BasisConversion/phased_rx-cz.qke b/test/Transforms/BasisConversion/phased_rx-cz.qke index 922a65ed90..d6e72f9133 100644 --- a/test/Transforms/BasisConversion/phased_rx-cz.qke +++ b/test/Transforms/BasisConversion/phased_rx-cz.qke @@ -6,8 +6,8 @@ // the terms of the Apache License 2.0 which accompanies this distribution. // // ========================================================================== // -// RUN: cudaq-opt -pass-pipeline='builtin.module(basis-conversion{basis=z(1),phased_rx,disable-patterns=R1ToU3})' %s | FileCheck %s -// RUN: cudaq-opt -pass-pipeline='builtin.module(basis-conversion{basis=z(1),phased_rx,disable-patterns=R1ToU3})' %s | CircuitCheck %s --up-to-global-phase +// RUN: cudaq-opt --basis-conversion="basis=z(1),phased_rx disable-patterns=R1ToU3" %s | FileCheck %s +// RUN: cudaq-opt --basis-conversion="basis=z(1),phased_rx disable-patterns=R1ToU3" %s | CircuitCheck %s --up-to-global-phase // CHECK-LABEL: func.func @cx From d6f84a595656896643d52bccc340a1d99251b6f7 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 25 Nov 2024 13:55:08 -0800 Subject: [PATCH 34/47] Made the tests work end to end Signed-off-by: Anna Gringauze --- include/cudaq/Optimizer/Transforms/Passes.td | 20 +- lib/Optimizer/CodeGen/Pipelines.cpp | 7 +- .../Transforms/CombineMeasurements.cpp | 42 +- program.py | 256 ----- python/tests/backends/test_braket.py | 12 +- runtime/common/BaseRemoteRESTQPU.h | 12 +- runtime/common/BraketExecutor.h | 4 + runtime/common/BraketServerHelper.h | 3 + .../rest/helpers/braket/BraketExecutor.cpp | 170 +-- .../helpers/braket/BraketServerHelper.cpp | 47 +- .../default/rest/helpers/braket/braket.yml | 3 +- test/Quake/combine_measurements.qke | 54 + tmp.qke | 17 - tmp.txt | 970 ------------------ 14 files changed, 227 insertions(+), 1390 deletions(-) delete mode 100644 program.py create mode 100644 test/Quake/combine_measurements.qke delete mode 100644 tmp.qke delete mode 100644 tmp.txt diff --git a/include/cudaq/Optimizer/Transforms/Passes.td b/include/cudaq/Optimizer/Transforms/Passes.td index 73ca0289ac..60ec50ac2a 100644 --- a/include/cudaq/Optimizer/Transforms/Passes.td +++ b/include/cudaq/Optimizer/Transforms/Passes.td @@ -143,9 +143,25 @@ def CheckKernelCalls : Pass<"check-kernel-calls", "mlir::func::FuncOp"> { def CombineMeasurements : Pass<"combine-measurements", "mlir::func::FuncOp"> { - let summary = "Combines mz operations and removes subveqs."; + let summary = "Extends mesurements on subveqs adds output names"; let description = [{ - TODO + Replace a pattern such as: + ``` + func.func @kernel() attributes {"cudaq-entrypoint"} { + %1 = ... : !quake.veq<4> + %2 = quake.subveq %1, %c2, %c3 : (!quake.veq<4>, i32, i32) -> + !quake.veq<2> + %measOut = quake.mz %2 : (!quake.veq<2>) -> !cc.stdvec + } + ``` + with: + ``` + func.func @kernel() attributes {"cudaq-entrypoint", ["output_names", + "[[[0,[1,\22q0\22]],[1,[2,\22q1\22]]]]"]} { + %1 = ... : !quake.veq<4> + %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec + } + ``` }]; let dependentDialects = ["cudaq::cc::CCDialect", "quake::QuakeDialect"]; } diff --git a/lib/Optimizer/CodeGen/Pipelines.cpp b/lib/Optimizer/CodeGen/Pipelines.cpp index c0e93517fe..187535a788 100644 --- a/lib/Optimizer/CodeGen/Pipelines.cpp +++ b/lib/Optimizer/CodeGen/Pipelines.cpp @@ -41,8 +41,8 @@ void cudaq::opt::commonPipelineConvertToQIR( pm.addPass(createConvertToQIR()); } -// TODO: remove passes from yml files? void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) { + // TODO: remove passes that are not common to all pipelines. pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); pm.addNestedPass(createClassicalMemToReg()); @@ -55,14 +55,15 @@ void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) { pm.addPass(createUnitarySynthesis()); pm.addPass(createSymbolDCEPass()); pm.addPass(createCanonicalizerPass()); - pm.addPass(createCSEPass()); pm.addNestedPass(createMultiControlDecompositionPass()); pm.addPass(createDecompositionPass( - {.enabledPatterns = {"R1ToU3","U3ToRotations","CCZToCX","CRzToCX", "RxAdjToRx", "RyAdjToRy", "RzAdjToRz", "SAdjToSZ"}})); + {.enabledPatterns = {"R1ToU3","U3ToRotations","CCZToCX","CRzToCX", + "RxAdjToRx", "RyAdjToRy", "RzAdjToRz", "SAdjToSZ"}})); pm.addNestedPass(createExpandControlVeqs()); pm.addNestedPass(createCombineQuantumAllocations()); pm.addNestedPass(createCombineMeasurements()); pm.addNestedPass(createCanonicalizerPass()); + pm.addPass(createSymbolDCEPass()); } void cudaq::opt::addPipelineTranslateToIQMJson(PassManager &pm) { diff --git a/lib/Optimizer/Transforms/CombineMeasurements.cpp b/lib/Optimizer/Transforms/CombineMeasurements.cpp index 37aea3db7c..988280bcc1 100644 --- a/lib/Optimizer/Transforms/CombineMeasurements.cpp +++ b/lib/Optimizer/Transforms/CombineMeasurements.cpp @@ -7,26 +7,18 @@ ******************************************************************************/ #include "PassDetails.h" -//#include "cudaq/Optimizer/Builder/Runtime.h" #include "cudaq/Optimizer/CodeGen/QIRAttributeNames.h" -//#include "cudaq/Optimizer/CodeGen/CudaqFunctionNames.h" #include "cudaq/Optimizer/Dialect/CC/CCOps.h" #include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h" #include "cudaq/Optimizer/Dialect/Quake/QuakeTypes.h" #include "cudaq/Optimizer/Transforms/Passes.h" +#include "nlohmann/json.hpp" #include "llvm/Support/Debug.h" -//#include "mlir/Conversion/LLVMCommon/TypeConverter.h" #include "mlir/Dialect/Arith/IR/Arith.h" -//#include "mlir/Dialect/Complex/IR/Complex.h" #include "mlir/Dialect/Func/IR/FuncOps.h" -//#include "mlir/Dialect/Math/IR/Math.h" #include "mlir/Pass/Pass.h" -//#include "mlir/Target/LLVMIR/TypeToLLVM.h" -//#include "mlir/Transforms/DialectConversion.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "mlir/Transforms/Passes.h" -//#include "mlir/Transforms/RegionUtils.h" -#include "nlohmann/json.hpp" namespace cudaq::opt { #define GEN_PASS_DEF_COMBINEMEASUREMENTS @@ -41,13 +33,14 @@ namespace { class ExtendMeasurePattern : public OpRewritePattern { using OutputNamesType = - std::map>; + std::map>; + public: using OpRewritePattern::OpRewritePattern; - explicit ExtendMeasurePattern(MLIRContext *ctx, OutputNamesType &resultQubitVals) - : OpRewritePattern(ctx), - resultQubitVals(resultQubitVals) {} + explicit ExtendMeasurePattern(MLIRContext *ctx, + OutputNamesType &resultQubitVals) + : OpRewritePattern(ctx), resultQubitVals(resultQubitVals) {} // Replace a pattern such as: // ``` @@ -60,7 +53,8 @@ class ExtendMeasurePattern : public OpRewritePattern { // ``` // with: // ``` - // func.func @kernel() attributes {"cudaq-entrypoint", ["output_names", "[[[0,[1,\22q0\22]],[1,[2,\22q1\22]]]]"]} { + // func.func @kernel() attributes {"cudaq-entrypoint", ["output_names", + // "[[[0,[1,\22q0\22]],[1,[2,\22q1\22]]]]"]} { // %1 = ... : !quake.veq<4> // %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec // } @@ -71,7 +65,7 @@ class ExtendMeasurePattern : public OpRewritePattern { measure.emitError("Only measures with no uses are supported"); return failure(); } - + auto veqOp = measure.getOperand(0); if (auto subveq = veqOp.getDefiningOp()) { Value lowOp = subveq.getLow(); @@ -81,27 +75,29 @@ class ExtendMeasurePattern : public OpRewritePattern { if (auto constHigh = highOp.getDefiningOp()) { auto high = static_cast(constHigh.value()); for (std::size_t i = low; i <= high; i++) { - // Note: regname is ignored for OpenQasm2 - resultQubitVals[i-low] = std::make_pair(i, std::to_string(i)); + // Note: regname is ignored for OpenQasm2 targets + resultQubitVals[i - low] = std::make_pair(i, std::to_string(i)); } - rewriter.replaceOpWithNewOp(measure, measure.getResultTypes(), subveq.getVeq()); + rewriter.replaceOpWithNewOp( + measure, measure.getResultTypes(), subveq.getVeq()); return success(); } } } - + return failure(); } + private: OutputNamesType &resultQubitVals; }; - class CombineMeasurementsPass : public cudaq::opt::impl::CombineMeasurementsBase< CombineMeasurementsPass> { using OutputNamesType = - std::map>; + std::map>; + public: using CombineMeasurementsBase::CombineMeasurementsBase; @@ -121,12 +117,12 @@ class CombineMeasurementsPass func.emitOpError("combining measurements failed"); signalPassFailure(); } - + // TODO: move measOut to the end of the func (see delayMeasurements?) if (!resultQubitVals.empty()) { nlohmann::json resultQubitJSON{resultQubitVals}; func->setAttr(cudaq::opt::QIROutputNamesAttrName, - builder.getStringAttr(resultQubitJSON.dump())); + builder.getStringAttr(resultQubitJSON.dump())); } LLVM_DEBUG(llvm::dbgs() << "Function after combining measurements:\n" diff --git a/program.py b/program.py deleted file mode 100644 index 3cb82ce50e..0000000000 --- a/program.py +++ /dev/null @@ -1,256 +0,0 @@ -# ============================================================================ # -# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. # -# All rights reserved. # -# # -# This source code and the accompanying materials are made available under # -# the terms of the Apache License 2.0 which accompanies this distribution. # -# ============================================================================ # - -import cudaq - -def test_kernel_subveqs(): - device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" - #device_arn = "arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet" - cudaq.set_target("braket", machine=device_arn) - #cudaq.set_target("ionq", emulate=True) - - @cudaq.kernel - def kernel(): - qubits = cudaq.qvector(4) - #h(qubits[0]) - # for qubit in range(3): - # x.ctrl(qubits[qubit], qubits[qubit + 1]) - x(qubits[1]) - x(qubits[2]) - v = qubits[1:3] - mz(v) - #mz(qubits) - - counts = cudaq.sample(kernel, shots_count=100) - print(counts) - # assert len(counts) == 2 - # assert "0000" in counts - # assert "1111" in counts - -test_kernel_subveqs() - -def test_kernel_veqs(): - device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" - cudaq.set_target("braket", emulate=True, machine=device_arn) - #cudaq.set_target("braket", machine=device_arn) - @cudaq.kernel - def kernel(): - qubits = cudaq.qvector(2) - h(qubits[0]) - cx(qubits[0], qubits[1]) - mz(qubits) - - result = cudaq.sample(kernel, shots_count=1000) - print(result) - -#test_kernel_veqs() - -# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { -# func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { -# %c1_i64 = arith.constant 1 : i64 -# %0 = quake.alloca !quake.veq<4> -# %1 = quake.extract_ref %0[0] : (!quake.veq<4>) -> !quake.ref -# quake.h %1 : (!quake.ref) -> () -# %2 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref -# quake.x [%1] %2 : (!quake.ref, !quake.ref) -> () -# %3 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref -# quake.x [%2] %3 : (!quake.ref, !quake.ref) -> () -# %4 = quake.extract_ref %0[3] : (!quake.veq<4>) -> !quake.ref -# quake.x [%3] %4 : (!quake.ref, !quake.ref) -> () -# %5 = quake.subveq %0, %c1_i64, %c1_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<1> -# %measOut = quake.mz %5 : (!quake.veq<1>) -> !cc.stdvec -# return -# } -# } - -# => - -# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { -# func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { -# %c1_i64 = arith.constant 1 : i64 -# %0 = quake.alloca !quake.veq<4> -# %1 = quake.extract_ref %0[0] : (!quake.veq<4>) -> !quake.ref -# quake.h %1 : (!quake.ref) -> () -# %2 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref -# quake.x [%1] %2 : (!quake.ref, !quake.ref) -> () -# %3 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref -# quake.x [%2] %3 : (!quake.ref, !quake.ref) -> () -# %4 = quake.extract_ref %0[3] : (!quake.veq<4>) -> !quake.ref -# quake.x [%3] %4 : (!quake.ref, !quake.ref) -> () -# #%5 = quake.subveq %0, %c1_i64, %c1_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<1> -# %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec # add mapping to output only %0[1] -# return -# } -# } - -# // -----// IR Dump After ConvertToQIR (quake-to-qir) ('builtin.module' operation) //----- // -# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { -# llvm.func @__quantum__rt__qubit_release_array(!llvm.ptr>) -# llvm.func @__quantum__qis__mz(!llvm.ptr>) -> !llvm.ptr> -# llvm.func @invokeWithControlQubits(i64, !llvm.ptr>, ptr>)>>, ...) -# llvm.func @__quantum__qis__x__ctl(!llvm.ptr>, !llvm.ptr>) -# llvm.func @__quantum__qis__h(!llvm.ptr>) -# llvm.func @__quantum__rt__array_get_element_ptr_1d(!llvm.ptr>, i64) -> !llvm.ptr -# llvm.func @__quantum__rt__qubit_allocate_array(i64) -> !llvm.ptr> -# llvm.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { -# %0 = llvm.mlir.constant(4 : i64) : i64 -# %1 = llvm.call @__quantum__rt__qubit_allocate_array(%0) : (i64) -> !llvm.ptr> -# %2 = llvm.mlir.constant(0 : i64) : i64 -# %3 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %2) : (!llvm.ptr>, i64) -> !llvm.ptr -# %4 = llvm.bitcast %3 : !llvm.ptr to !llvm.ptr>> -# %5 = llvm.load %4 : !llvm.ptr>> -# llvm.call @__quantum__qis__h(%5) : (!llvm.ptr>) -> () -# %6 = llvm.mlir.constant(1 : i64) : i64 -# %7 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %6) : (!llvm.ptr>, i64) -> !llvm.ptr -# %8 = llvm.bitcast %7 : !llvm.ptr to !llvm.ptr>> -# %9 = llvm.load %8 : !llvm.ptr>> -# %10 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> -# %11 = llvm.mlir.constant(1 : i64) : i64 -# llvm.call @invokeWithControlQubits(%11, %10, %5, %9) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () -# %12 = llvm.mlir.constant(2 : i64) : i64 -# %13 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %12) : (!llvm.ptr>, i64) -> !llvm.ptr -# %14 = llvm.bitcast %13 : !llvm.ptr to !llvm.ptr>> -# %15 = llvm.load %14 : !llvm.ptr>> -# %16 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> -# %17 = llvm.mlir.constant(1 : i64) : i64 -# llvm.call @invokeWithControlQubits(%17, %16, %9, %15) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () -# %18 = llvm.mlir.constant(3 : i64) : i64 -# %19 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %18) : (!llvm.ptr>, i64) -> !llvm.ptr -# %20 = llvm.bitcast %19 : !llvm.ptr to !llvm.ptr>> -# %21 = llvm.load %20 : !llvm.ptr>> -# %22 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> -# %23 = llvm.mlir.constant(1 : i64) : i64 -# llvm.call @invokeWithControlQubits(%23, %22, %15, %21) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () -# %24 = llvm.mlir.constant(1 : i32) : i32 -# %25 = llvm.alloca %24 x !llvm.array<2 x i8> : (i32) -> !llvm.ptr> -# %26 = llvm.mlir.addressof @cstr.72303030303000 : !llvm.ptr> -# %27 = llvm.bitcast %26 : !llvm.ptr> to !llvm.ptr -# %28 = llvm.call @__quantum__qis__mz(%9) {registerName = "r00000"} : (!llvm.ptr>) -> !llvm.ptr> -# %29 = llvm.bitcast %28 : !llvm.ptr> to !llvm.ptr -# %30 = llvm.load %29 : !llvm.ptr -# %31 = llvm.bitcast %25 : !llvm.ptr> to !llvm.ptr -# %32 = llvm.zext %30 : i1 to i8 -# llvm.store %32, %31 : !llvm.ptr -# %33 = llvm.mlir.addressof @cstr.72303030303100 : !llvm.ptr> -# %34 = llvm.bitcast %33 : !llvm.ptr> to !llvm.ptr -# %35 = llvm.call @__quantum__qis__mz(%15) {registerName = "r00001"} : (!llvm.ptr>) -> !llvm.ptr> -# %36 = llvm.bitcast %35 : !llvm.ptr> to !llvm.ptr -# %37 = llvm.load %36 : !llvm.ptr -# %38 = llvm.getelementptr %25[0, 1] : (!llvm.ptr>) -> !llvm.ptr -# %39 = llvm.zext %37 : i1 to i8 -# llvm.store %39, %38 : !llvm.ptr -# llvm.call @__quantum__rt__qubit_release_array(%1) : (!llvm.ptr>) -> () -# llvm.return -# } -# llvm.mlir.global private constant @cstr.72303030303000("r00000\00") {addr_space = 0 : i32} -# llvm.mlir.global private constant @cstr.72303030303100("r00001\00") {addr_space = 0 : i32} -# } - -# // -----// IR Dump After Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { -# func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { -# %c2_i64 = arith.constant 2 : i64 -# %c1_i64 = arith.constant 1 : i64 -# %0 = quake.alloca !quake.veq<4> -# %1 = quake.extract_ref %0[0] : (!quake.veq<4>) -> !quake.ref -# quake.h %1 : (!quake.ref) -> () -# %2 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref -# quake.x [%1] %2 : (!quake.ref, !quake.ref) -> () -# %3 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref -# quake.x [%2] %3 : (!quake.ref, !quake.ref) -> () -# %4 = quake.extract_ref %0[3] : (!quake.veq<4>) -> !quake.ref -# quake.x [%3] %4 : (!quake.ref, !quake.ref) -> () -# %5 = quake.subveq %0, %c1_i64, %c2_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<2> -# %measOut = quake.mz %5 : (!quake.veq<2>) -> !cc.stdvec -# return -# } -# } - -# // IONQ: - - -# // -----// IR Dump After QIRToQIRProfileFunc (quake-to-qir-func) ('llvm.func' operation: @__nvqpp__mlirgen__kernel) //----- // -# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { -# llvm.func @__quantum__qis__h__body(!llvm.ptr>) -# llvm.func @__quantum__qis__cnot__body(!llvm.ptr>, !llvm.ptr>) -# llvm.func @__quantum__qis__cz__body(!llvm.ptr>, !llvm.ptr>) -# llvm.func @__quantum__rt__result_record_output(!llvm.ptr>, !llvm.ptr) -# llvm.func @__quantum__qis__read_result__body(!llvm.ptr>) -> i1 -# llvm.func @__quantum__qis__mz__body(!llvm.ptr>, !llvm.ptr>) attributes {passthrough = ["irreversible"]} -# llvm.func @__quantum__qis__cz(!llvm.ptr>, !llvm.ptr>) -# llvm.func @__quantum__qis__cnot(!llvm.ptr>, !llvm.ptr>) -# llvm.func @__quantum__rt__qubit_release_array(!llvm.ptr>) -# llvm.func @__quantum__qis__mz(!llvm.ptr>) -> !llvm.ptr> attributes {passthrough = ["irreversible"]} -# llvm.func @invokeWithControlQubits(i64, !llvm.ptr>, ptr>)>>, ...) -# llvm.func @__quantum__qis__x__ctl(!llvm.ptr>, !llvm.ptr>) -# llvm.func @__quantum__qis__h(!llvm.ptr>) -# llvm.func @__quantum__rt__array_get_element_ptr_1d(!llvm.ptr>, i64) -> !llvm.ptr -# llvm.func @__quantum__rt__qubit_allocate_array(i64) -> !llvm.ptr> -# llvm.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", passthrough = ["entry_point", ["qir_profiles", "base_profile"], ["output_labeling_schema", "schema_id"], ["output_names", "[[[0,[1,\22r00000\22]],[1,[2,\22r00001\22]]]]"], ["requiredQubits", "4"], ["requiredResults", "2"]]} { -# %0 = llvm.mlir.constant(4 : i64) : i64 -# %1 = llvm.call @__quantum__rt__qubit_allocate_array(%0) {StartingOffset = 0 : i64} : (i64) -> !llvm.ptr> -# %2 = llvm.mlir.constant(0 : i64) : i64 -# %3 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %2) : (!llvm.ptr>, i64) -> !llvm.ptr -# %4 = llvm.bitcast %3 : !llvm.ptr to !llvm.ptr>> -# %5 = llvm.load %4 : !llvm.ptr>> -# llvm.call @__quantum__qis__h(%5) : (!llvm.ptr>) -> () -# %6 = llvm.mlir.constant(1 : i64) : i64 -# %7 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %6) : (!llvm.ptr>, i64) -> !llvm.ptr -# %8 = llvm.bitcast %7 : !llvm.ptr to !llvm.ptr>> -# %9 = llvm.load %8 : !llvm.ptr>> -# %10 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> -# %11 = llvm.mlir.constant(1 : i64) : i64 -# llvm.call @invokeWithControlQubits(%11, %10, %5, %9) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () -# %12 = llvm.mlir.constant(2 : i64) : i64 -# %13 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %12) : (!llvm.ptr>, i64) -> !llvm.ptr -# %14 = llvm.bitcast %13 : !llvm.ptr to !llvm.ptr>> -# %15 = llvm.load %14 : !llvm.ptr>> -# %16 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> -# %17 = llvm.mlir.constant(1 : i64) : i64 -# llvm.call @invokeWithControlQubits(%17, %16, %9, %15) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () -# %18 = llvm.mlir.constant(3 : i64) : i64 -# %19 = llvm.call @__quantum__rt__array_get_element_ptr_1d(%1, %18) : (!llvm.ptr>, i64) -> !llvm.ptr -# %20 = llvm.bitcast %19 : !llvm.ptr to !llvm.ptr>> -# %21 = llvm.load %20 : !llvm.ptr>> -# %22 = llvm.mlir.addressof @__quantum__qis__x__ctl : !llvm.ptr>, ptr>)>> -# %23 = llvm.mlir.constant(1 : i64) : i64 -# llvm.call @invokeWithControlQubits(%23, %22, %15, %21) : (i64, !llvm.ptr>, ptr>)>>, !llvm.ptr>, !llvm.ptr>) -> () -# %24 = llvm.mlir.constant(1 : i32) : i32 -# %25 = llvm.alloca %24 x !llvm.array<2 x i8> : (i32) -> !llvm.ptr> -# %26 = llvm.bitcast %25 : !llvm.ptr> to !llvm.ptr -# %27 = llvm.getelementptr %25[0, 1] : (!llvm.ptr>) -> !llvm.ptr -# %28 = llvm.mlir.addressof @cstr.72303030303000 : !llvm.ptr> -# %29 = llvm.bitcast %28 : !llvm.ptr> to !llvm.ptr -# %30 = llvm.call @__quantum__qis__mz(%9) {registerName = "r00000", result.index = 0 : i64} : (!llvm.ptr>) -> !llvm.ptr> -# %31 = llvm.bitcast %30 : !llvm.ptr> to !llvm.ptr -# %32 = llvm.load %31 : !llvm.ptr -# %33 = llvm.zext %32 : i1 to i8 -# llvm.store %33, %26 : !llvm.ptr -# %34 = llvm.mlir.addressof @cstr.72303030303100 : !llvm.ptr> -# %35 = llvm.bitcast %34 : !llvm.ptr> to !llvm.ptr -# %36 = llvm.call @__quantum__qis__mz(%15) {registerName = "r00001", result.index = 1 : i64} : (!llvm.ptr>) -> !llvm.ptr> -# %37 = llvm.bitcast %36 : !llvm.ptr> to !llvm.ptr -# %38 = llvm.load %37 : !llvm.ptr -# %39 = llvm.zext %38 : i1 to i8 -# llvm.store %39, %27 : !llvm.ptr -# llvm.call @__quantum__rt__qubit_release_array(%1) : (!llvm.ptr>) -> () -# %40 = llvm.mlir.constant(0 : i64) : i64 -# %41 = llvm.inttoptr %40 : i64 to !llvm.ptr> -# %42 = llvm.mlir.addressof @cstr.72303030303000 : !llvm.ptr> -# %43 = llvm.bitcast %42 : !llvm.ptr> to !llvm.ptr -# llvm.call @__quantum__rt__result_record_output(%41, %43) : (!llvm.ptr>, !llvm.ptr) -> () -# %44 = llvm.mlir.constant(1 : i64) : i64 -# %45 = llvm.inttoptr %44 : i64 to !llvm.ptr> -# %46 = llvm.mlir.addressof @cstr.72303030303100 : !llvm.ptr> -# %47 = llvm.bitcast %46 : !llvm.ptr> to !llvm.ptr -# llvm.call @__quantum__rt__result_record_output(%45, %47) : (!llvm.ptr>, !llvm.ptr) -> () -# llvm.return -# } -# llvm.mlir.global private constant @cstr.72303030303000("r00000\00") {addr_space = 0 : i32} -# llvm.mlir.global private constant @cstr.72303030303100("r00001\00") {addr_space = 0 : i32} -# } \ No newline at end of file diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index dd2632c49e..b56e92fac7 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -277,16 +277,14 @@ def test_kernel_subveqs(): @cudaq.kernel def kernel(): qreg = cudaq.qvector(4) - h(qreg[0]) - for qubit in range(3): - x.ctrl(qreg[qubit], qreg[qubit + 1]) - v = qreg[1:2] + x(qreg[1]) + x(qreg[2]) + v = qreg[1:3] mz(v) counts = cudaq.sample(kernel, 4, shots_count=100) - assert len(counts) == 2 - assert "0000" in counts - assert "1111" in counts + assert len(counts) == 1 + assert "11" in counts @pytest.mark.parametrize("device_arn", [ diff --git a/runtime/common/BaseRemoteRESTQPU.h b/runtime/common/BaseRemoteRESTQPU.h index 79d6116b00..7cf42b3680 100644 --- a/runtime/common/BaseRemoteRESTQPU.h +++ b/runtime/common/BaseRemoteRESTQPU.h @@ -333,7 +333,8 @@ class BaseRemoteRESTQPU : public cudaq::QPU { } /// @brief Conditionally form an output_names JSON object if this was for QIR - nlohmann::json formOutputNames(const std::string &codegenTranslation, mlir::ModuleOp moduleOp, + nlohmann::json formOutputNames(const std::string &codegenTranslation, + mlir::ModuleOp moduleOp, const std::string &codeStr) { // Form an output_names mapping from codeStr nlohmann::json output_names; @@ -362,8 +363,10 @@ class BaseRemoteRESTQPU : public cudaq::QPU { } } else if (codegenTranslation.starts_with("qasm2")) { for (auto &op : moduleOp) { - if (op.hasAttr(cudaq::entryPointAttrName) && op.hasAttr("output_names")) { - if (auto strAttr = op.getAttr(cudaq::opt::QIROutputNamesAttrName).dyn_cast_or_null()) { + if (op.hasAttr(cudaq::entryPointAttrName) && + op.hasAttr("output_names")) { + if (auto strAttr = op.getAttr(cudaq::opt::QIROutputNamesAttrName) + .dyn_cast_or_null()) { output_names = nlohmann::json::parse(strAttr.getValue()); break; } @@ -566,7 +569,8 @@ class BaseRemoteRESTQPU : public cudaq::QPU { moduleOpI.dump(); std::cout << "CODE STR: " << codeStr << std::endl; // Form an output_names mapping from codeStr - nlohmann::json j = formOutputNames(codegenTranslation, moduleOpI, codeStr); + nlohmann::json j = + formOutputNames(codegenTranslation, moduleOpI, codeStr); codes.emplace_back(name, codeStr, j, mapping_reorder_idx); } diff --git a/runtime/common/BraketExecutor.h b/runtime/common/BraketExecutor.h index 4c9ff33802..7f5e1fc5e7 100644 --- a/runtime/common/BraketExecutor.h +++ b/runtime/common/BraketExecutor.h @@ -68,6 +68,10 @@ class BraketExecutor : public Executor { virtual ServerJobPayload checkHelperAndCreateJob(std::vector &codesToExecute); + /// @brief Utility function to set the output qubits for a task. + void setOutputNames(const KernelExecution &codeToExecute, + const std::string &taskId); + public: BraketExecutor(); diff --git a/runtime/common/BraketServerHelper.h b/runtime/common/BraketServerHelper.h index c718d2b8c3..32f0d4695e 100644 --- a/runtime/common/BraketServerHelper.h +++ b/runtime/common/BraketServerHelper.h @@ -83,6 +83,9 @@ class BraketServerHelper : public ServerHelper { cudaq::sample_result processResults(ServerMessage &postJobResponse, std::string &jobId) override; + void setOutputNames(const std::string &taskId, + const std::string &output_names); + protected: /// @brief Return the headers required for the REST calls RestHeaders generateRequestHeader() const; diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp index ba913dff93..159ae0bcd6 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp @@ -162,106 +162,118 @@ ServerJobPayload BraketExecutor::checkHelperAndCreateJob( return braketServerHelper->createJob(codesToExecute); } +void BraketExecutor::setOutputNames(const KernelExecution &codeToExecute, + const std::string &taskId) { + auto braketServerHelper = dynamic_cast(serverHelper); + assert(braketServerHelper); + auto config = braketServerHelper->getConfig(); + + auto output_names = codeToExecute.output_names.dump(); + config["output_names." + taskId] = output_names; + + braketServerHelper->setOutputNames(taskId, output_names); +} + details::future BraketExecutor::execute(std::vector &codesToExecute) { - // auto [dummy1, dummy2, messages] = checkHelperAndCreateJob(codesToExecute); + auto [dummy1, dummy2, messages] = checkHelperAndCreateJob(codesToExecute); - // std::string const defaultBucket = defaultBucketFuture.get(); - // std::string const defaultPrefix = "tasks"; + std::string const defaultBucket = defaultBucketFuture.get(); + std::string const defaultPrefix = "tasks"; - // std::vector - // createOutcomes; + std::vector + createOutcomes; - // for (const auto &message : messages) { - // Aws::Braket::Model::CreateQuantumTaskRequest req; - // req.SetAction(message["action"]); - // req.SetDeviceArn(message["deviceArn"]); - // req.SetShots(message["shots"]); - // if (jobToken) - // req.SetJobToken(jobToken); - // req.SetOutputS3Bucket(defaultBucket); - // req.SetOutputS3KeyPrefix(defaultPrefix); + for (const auto &message : messages) { + Aws::Braket::Model::CreateQuantumTaskRequest req; + req.SetAction(message["action"]); + req.SetDeviceArn(message["deviceArn"]); + req.SetShots(message["shots"]); + if (jobToken) + req.SetJobToken(jobToken); + req.SetOutputS3Bucket(defaultBucket); + req.SetOutputS3KeyPrefix(defaultPrefix); - // createOutcomes.push_back(braketClientPtr->CreateQuantumTaskCallable(req)); - // } + createOutcomes.push_back(braketClientPtr->CreateQuantumTaskCallable(req)); + } return std::async( std::launch::async, - [this](/*std::vector - createOutcomes*/) { + [this, codesToExecute]( + std::vector + createOutcomes) { std::vector results; - //for (auto &outcome : createOutcomes) { - // auto createResponse = outcome.get(); - // if (!createResponse.IsSuccess()) { - // throw std::runtime_error(createResponse.GetError().GetMessage()); - // } - // std::string taskArn = createResponse.GetResult().GetQuantumTaskArn(); - - // cudaq::info("Created Braket quantum task {}", taskArn); - - // Aws::Braket::Model::GetQuantumTaskRequest req; - // req.SetQuantumTaskArn(taskArn); - // auto getResponse = braketClientPtr->GetQuantumTask(req); - // if (!getResponse.IsSuccess()) { - // throw std::runtime_error(getResponse.GetError().GetMessage()); - // } - // auto taskStatus = getResponse.GetResult().GetStatus(); - // while ( - // taskStatus != Aws::Braket::Model::QuantumTaskStatus::COMPLETED && - // taskStatus != Aws::Braket::Model::QuantumTaskStatus::FAILED && - // taskStatus != Aws::Braket::Model::QuantumTaskStatus::CANCELLED) { - // std::this_thread::sleep_for(pollingInterval); - - // getResponse = braketClientPtr->GetQuantumTask(req); - // if (!getResponse.IsSuccess()) { - // throw std::runtime_error(getResponse.GetError().GetMessage()); - // } - // taskStatus = getResponse.GetResult().GetStatus(); - // } - - // auto getResult = getResponse.GetResult(); - // if (taskStatus != Aws::Braket::Model::QuantumTaskStatus::COMPLETED) { - // // Task terminated without results - // throw std::runtime_error( - // fmt::format("Braket task {} terminated without results. {}", - // taskArn, getResult.GetFailureReason())); - // } - - // std::string outBucket = getResult.GetOutputS3Bucket(); - // std::string outPrefix = getResult.GetOutputS3Directory(); - - // cudaq::info("Fetching braket quantum task {} results from " - // "s3://{}/{}/results.json", - // taskArn, outBucket, outPrefix); - - // Aws::S3Crt::Model::GetObjectRequest resultsJsonRequest; - // resultsJsonRequest.SetBucket(outBucket); - // resultsJsonRequest.SetKey(fmt::format("{}/results.json", outPrefix)); - // auto s3Response = s3ClientPtr->GetObject(resultsJsonRequest); - // if (!s3Response.IsSuccess()) { - // throw std::runtime_error(s3Response.GetError().GetMessage()); - // } - // auto resultsJson = nlohmann::json::parse( - // s3Response.GetResultWithOwnership().GetBody()); - std::string taskArn = "arn:aws:braket:us-east-1:783764578061:quantum-task/8bad9d49-b546-4ed8-8517-1b23c1eb929e"; - auto resultsJson = nlohmann::json::parse("{\"additionalMetadata\":{\"action\":{\"braketSchemaHeader\":{\"name\":\"braket.ir.openqasm.program\",\"version\":\"1\"},\"inputs\":{},\"source\":\"// Code generated by NVIDIA's nvq++ compiler\\nOPENQASM 2.0;\\n\\n\\n\\nqreg var0[4];\\nx var0[1];\\nx var0[2];\\ncreg var3[4];\\nmeasure var0 -> var3;\\n\"},\"simulatorMetadata\":{\"braketSchemaHeader\":{\"name\":\"braket.task_result.simulator_metadata\",\"version\":\"1\"},\"executionDuration\":2}},\"braketSchemaHeader\":{\"name\":\"braket.task_result.gate_model_task_result\",\"version\":\"1\"},\"measuredQubits\":[0,1,2,3],\"measurements\":[[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0]],\"resultTypes\":[],\"taskMetadata\":{\"braketSchemaHeader\":{\"name\":\"braket.task_result.task_metadata\",\"version\":\"1\"},\"createdAt\":\"2024-11-23T19:16:08.872Z\",\"deviceId\":\"arn:aws:braket:::device/quantum-simulator/amazon/sv1\",\"deviceParameters\":{\"braketSchemaHeader\":{\"name\":\"braket.device_schema.simulators.gate_model_simulator_device_parameters\",\"version\":\"1\"},\"paradigmParameters\":{\"braketSchemaHeader\":{\"name\":\"braket.device_schema.gate_model_parameters\",\"version\":\"1\"},\"disableQubitRewiring\":false,\"qubitCount\":4}},\"endedAt\":\"2024-11-23T19:16:10.138Z\",\"id\":\"arn:aws:braket:us-east-1:783764578061:quantum-task/8bad9d49-b546-4ed8-8517-1b23c1eb929e\",\"shots\":100,\"status\":\"COMPLETED\"}}"); - std::cout << "Results: " << resultsJson << std::endl; + for (std::size_t i = 0; auto &outcome : createOutcomes) { + auto createResponse = outcome.get(); + if (!createResponse.IsSuccess()) { + throw std::runtime_error(createResponse.GetError().GetMessage()); + } + std::string taskArn = createResponse.GetResult().GetQuantumTaskArn(); + + cudaq::info("Created Braket quantum task {}", taskArn); + setOutputNames(codesToExecute[i], taskArn); + + Aws::Braket::Model::GetQuantumTaskRequest req; + req.SetQuantumTaskArn(taskArn); + auto getResponse = braketClientPtr->GetQuantumTask(req); + if (!getResponse.IsSuccess()) { + throw std::runtime_error(getResponse.GetError().GetMessage()); + } + auto taskStatus = getResponse.GetResult().GetStatus(); + while ( + taskStatus != Aws::Braket::Model::QuantumTaskStatus::COMPLETED && + taskStatus != Aws::Braket::Model::QuantumTaskStatus::FAILED && + taskStatus != Aws::Braket::Model::QuantumTaskStatus::CANCELLED) { + std::this_thread::sleep_for(pollingInterval); + + getResponse = braketClientPtr->GetQuantumTask(req); + if (!getResponse.IsSuccess()) { + throw std::runtime_error(getResponse.GetError().GetMessage()); + } + taskStatus = getResponse.GetResult().GetStatus(); + } + + auto getResult = getResponse.GetResult(); + if (taskStatus != Aws::Braket::Model::QuantumTaskStatus::COMPLETED) { + // Task terminated without results + throw std::runtime_error( + fmt::format("Braket task {} terminated without results. {}", + taskArn, getResult.GetFailureReason())); + } + + std::string outBucket = getResult.GetOutputS3Bucket(); + std::string outPrefix = getResult.GetOutputS3Directory(); + + cudaq::info("Fetching braket quantum task {} results from " + "s3://{}/{}/results.json", + taskArn, outBucket, outPrefix); + + Aws::S3Crt::Model::GetObjectRequest resultsJsonRequest; + resultsJsonRequest.SetBucket(outBucket); + resultsJsonRequest.SetKey(fmt::format("{}/results.json", outPrefix)); + auto s3Response = s3ClientPtr->GetObject(resultsJsonRequest); + if (!s3Response.IsSuccess()) { + throw std::runtime_error(s3Response.GetError().GetMessage()); + } + auto resultsJson = nlohmann::json::parse( + s3Response.GetResultWithOwnership().GetBody()); + auto c = serverHelper->processResults(resultsJson, taskArn); for (auto ®Name : c.register_names()) { std::cout << "Register name: " << regName << std::endl; results.emplace_back(c.to_map(regName), regName); std::cout << "Sequential data: " << regName << std::endl; - for(auto d: c.sequential_data(regName)) { + for (auto d : c.sequential_data(regName)) { std::cout << d << std::endl; } results.back().sequentialData = c.sequential_data(regName); } - //} - + i++; + } return sample_result(results); - }/*, - std::move(createOutcomes)*/); + }, + std::move(createOutcomes)); } } // namespace cudaq diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp index e709846ac1..f5cfb96a4a 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp @@ -7,7 +7,6 @@ ******************************************************************************/ #include "common/BraketServerHelper.h" -#include namespace { std::string prepareOpenQasm(std::string source) { @@ -116,15 +115,10 @@ BraketServerHelper::createJob(std::vector &circuitCodes) { sample_result BraketServerHelper::processResults(ServerMessage &resultsJson, std::string &jobID) { - //if (outputNames.find(jobID) == outputNames.end()) - // throw std::runtime_error("Could not find output names for job " + jobID); - - //auto &output_names = outputNames[jobID]; - // Fake output names - cudaq::OutputNamesType output_names; - output_names[0] = cudaq::ResultInfoType{1, "1"}; - output_names[1] = cudaq::ResultInfoType{2, "2"}; + if (outputNames.find(jobID) == outputNames.end()) + throw std::runtime_error("Could not find output names for job " + jobID); + auto &output_names = outputNames[jobID]; for (auto &[result, info] : output_names) { cudaq::info("Qubit {} Result {} Name {}", info.qubitNum, result, info.registerName); @@ -152,16 +146,6 @@ sample_result BraketServerHelper::processResults(ServerMessage &resultsJson, } } - std::cout << "COUNTS: " << std::endl; - for (auto c: counts) { - std::cout << c.first << ": " << c.second <(); + auto qubitNum = el[1][0].get(); + auto registerName = el[1][1].get(); + jobOutputNames[result] = {qubitNum, registerName}; + } - //return sample_result{ExecutionResult{counts}}; + outputNames[taskId] = jobOutputNames; } } // namespace cudaq diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index db5baa7dcc..11bf1e6735 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,8 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0},expand-control-veqs,canonicalize,combine-quantum-alloc),symbol-dce" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ}" + #platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0},expand-control-veqs,canonicalize,combine-quantum-alloc),symbol-dce" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Additional passes to run after lowering to QUAKE diff --git a/test/Quake/combine_measurements.qke b/test/Quake/combine_measurements.qke new file mode 100644 index 0000000000..f3dfa77555 --- /dev/null +++ b/test/Quake/combine_measurements.qke @@ -0,0 +1,54 @@ +// ========================================================================== // +// Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. // +// All rights reserved. // +// // +// This source code and the accompanying materials are made available under // +// the terms of the Apache License 2.0 which accompanies this distribution. // +// ========================================================================== // + +// RUN: cudaq-opt -combine-measurements -canonicalize %s | FileCheck %s +module { + func.func @subveq_4_1() attributes {"cudaq-entrypoint"} { + %c1_i64 = arith.constant 1 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.subveq %0, %c1_i64, %c1_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<1> + %measOut = quake.mz %1 : (!quake.veq<1>) -> !cc.stdvec + return + } + +// CHECK: func.func @subveq_4_1() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec +// CHECK: return +// CHECK: } + + func.func @subveq_4_2() attributes {"cudaq-entrypoint"} { + %c1_i64 = arith.constant 1 : i64 + %c2_i64 = arith.constant 2 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.subveq %0, %c1_i64, %c2_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<2> + %measOut = quake.mz %1 : (!quake.veq<2>) -> !cc.stdvec + return + } + +// CHECK: func.func @subveq_4_2() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\],\[1,\[2,\\222\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec +// CHECK: return +// CHECK: } + + func.func @subveq_4_4() attributes {"cudaq-entrypoint"} { + %c0_i64 = arith.constant 0 : i64 + %c3_i64 = arith.constant 3 : i64 + %0 = quake.alloca !quake.veq<4> + %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> + %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec + return + } + +// CHECK: func.func @subveq_4_4() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[1,\[1,\\221\\22\]\],\[2,\[2,\\222\\22\]\],\[3,\[3,\\223\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec +// CHECK: return +// CHECK: } +} \ No newline at end of file diff --git a/tmp.qke b/tmp.qke deleted file mode 100644 index 490f965031..0000000000 --- a/tmp.qke +++ /dev/null @@ -1,17 +0,0 @@ -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %c1_i64 = arith.constant 1 : i64 - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[0] : (!quake.veq<4>) -> !quake.ref - quake.h %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x [%1] %2 : (!quake.ref, !quake.ref) -> () - %3 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x [%2] %3 : (!quake.ref, !quake.ref) -> () - %4 = quake.extract_ref %0[3] : (!quake.veq<4>) -> !quake.ref - quake.x [%3] %4 : (!quake.ref, !quake.ref) -> () - %5 = quake.subveq %0, %c1_i64, %c1_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<1> - %measOut = quake.mz %5 : (!quake.veq<1>) -> !cc.stdvec - return - } -} \ No newline at end of file diff --git a/tmp.txt b/tmp.txt deleted file mode 100644 index 80928883a5..0000000000 --- a/tmp.txt +++ /dev/null @@ -1,970 +0,0 @@ -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:205] Init infrastructure for pythonic builder. -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target anyon with config file anyon.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: anyon -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target braket with config file braket.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: braket -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target density-matrix-cpu with config file density-matrix-cpu.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use dm simulator for target density-matrix-cpu -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: density-matrix-cpu -> (sim=dm, platform=default) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target fermioniq with config file fermioniq.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: fermioniq -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target ionq with config file ionq.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: ionq -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target iqm with config file iqm.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: iqm -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia-fp64 with config file nvidia-fp64.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp64 simulator for target nvidia-fp64 since it is not available -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp64 simulator for target nvidia-fp64 -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia-fp64 -> (sim=custatevec_fp64, platform=default) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia-mqpu-fp64 with config file nvidia-mqpu-fp64.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp64 simulator for target nvidia-mqpu-fp64 since it is not available -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp64 simulator for target nvidia-mqpu-fp64 -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia-mqpu-fp64 -> (sim=custatevec_fp64, platform=mqpu) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia-mqpu-mps with config file nvidia-mqpu-mps.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use tensornet-mps simulator for target nvidia-mqpu-mps -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia-mqpu-mps -> (sim=tensornet_mps, platform=mqpu) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia-mqpu with config file nvidia-mqpu.yml -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp32 simulator for target nvidia-mqpu since it is not available -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp32 simulator for target nvidia-mqpu -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia-mqpu -> (sim=custatevec_fp32, platform=mqpu) -[2024-11-24 19:46:56.079] [info] [LinkedLibraryHolder.cpp:185] Found Target nvidia with config file nvidia.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp32 simulator for target nvidia since it is not available -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp32 simulator for target nvidia -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvidia -> (sim=custatevec_fp32, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target nvqc with config file nvqc.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: nvqc -> (sim=qpp, platform=mqpu) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target opt-test with config file opt-test.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp32 simulator for target opt-test since it is not available -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp32 simulator for target opt-test -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: opt-test -> (sim=custatevec_fp32, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target oqc with config file oqc.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: oqc -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target orca-photonics with config file orca-photonics.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: orca-photonics -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target orca with config file orca.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: orca -> (sim=qpp, platform=mqpu) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target qpp-cpu with config file qpp-cpu.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use qpp simulator for target qpp-cpu -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: qpp-cpu -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target quantinuum with config file quantinuum.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: quantinuum -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target quera with config file quera.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: quera -> (sim=qpp, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target remote-mqpu with config file remote-mqpu.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: remote-mqpu -> (sim=qpp, platform=mqpu) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target stim with config file stim.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use stim simulator for target stim -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: stim -> (sim=stim, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target tensornet-mps with config file tensornet-mps.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use tensornet-mps simulator for target tensornet-mps -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: tensornet-mps -> (sim=tensornet_mps, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:185] Found Target tensornet with config file tensornet.yml -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:135] Use tensornet simulator for target tensornet -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:195] Found Target: tensornet -> (sim=tensornet, platform=default) -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:230] Init: Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.080] [info] [LinkedLibraryHolder.cpp:322] Found platform plugin default. -[2024-11-24 19:46:56.081] [info] [LinkedLibraryHolder.cpp:322] Found platform plugin mqpu. -[2024-11-24 19:46:56.094] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin custatevec_fp32. -[2024-11-24 19:46:56.094] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin custatevec_fp64. -[2024-11-24 19:46:56.094] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin custatevec_kernels. -[2024-11-24 19:46:56.095] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin dm. -[2024-11-24 19:46:56.095] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin qpp. -[2024-11-24 19:46:56.095] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin stim. -[2024-11-24 19:46:56.099] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin tensornet_mps. -[2024-11-24 19:46:56.099] [info] [LinkedLibraryHolder.cpp:301] Found simulator plugin tensornet. -[2024-11-24 19:46:56.160] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.160] [info] [LinkedLibraryHolder.cpp:140] Skip cusvsim-fp32 simulator for target nvidia since it is not available -[2024-11-24 19:46:56.160] [info] [LinkedLibraryHolder.cpp:129] CUDA-Q Library Path is /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../lib. -[2024-11-24 19:46:56.160] [info] [LinkedLibraryHolder.cpp:135] Use custatevec-fp32 simulator for target nvidia -[2024-11-24 19:46:56.161] [info] [LinkedLibraryHolder.cpp:455] Setting target=nvidia (sim=custatevec_fp32, platform=default) -[2024-11-24 19:46:56.161] [info] [PluginUtils.h:24] Requesting N5nvqir16CircuitSimulatorE plugin via symbol name getCircuitSimulator_custatevec_fp32. -[2024-11-24 19:46:56.161] [info] [PluginUtils.h:36] Successfully loaded the plugin. -[2024-11-24 19:46:56.310] [info] [NVQIR.cpp:70] [runtime] Setting the circuit simulator to custatevec-fp32. -[2024-11-24 19:46:56.310] [info] [PluginUtils.h:24] Requesting N5cudaq16quantum_platformE plugin via symbol name getQuantumPlatform_default. -[2024-11-24 19:46:56.310] [info] [PluginUtils.h:36] Successfully loaded the plugin. -[2024-11-24 19:46:56.310] [info] [DefaultQuantumPlatform.cpp:87] Backend string is nvidia -[2024-11-24 19:46:56.310] [info] [DefaultQuantumPlatform.cpp:104] Config file path = /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../targets/nvidia.yml -[2024-11-24 19:46:56.311] [info] [quantum_platform.cpp:37] external caller setting the platform. -[2024-11-24 19:46:56.311] [info] [execution_manager.cpp:21] external caller clearing the execution manager. -[2024-11-24 19:46:56.405] [info] [CUDAQuantumExtension.cpp:67] Calling initialize_cudaq. -[2024-11-24 19:46:56.405] [info] [LinkedLibraryHolder.cpp:455] Setting target=braket (sim=qpp, platform=default) -[2024-11-24 19:46:56.405] [info] [PluginUtils.h:24] Requesting N5nvqir16CircuitSimulatorE plugin via symbol name getCircuitSimulator_qpp. -[2024-11-24 19:46:56.405] [info] [PluginUtils.h:36] Successfully loaded the plugin. -[2024-11-24 19:46:56.405] [info] [NVQIR.cpp:70] [runtime] Setting the circuit simulator to qpp. -[2024-11-24 19:46:56.405] [info] [PluginUtils.h:24] Requesting N5cudaq16quantum_platformE plugin via symbol name getQuantumPlatform_default. -[2024-11-24 19:46:56.405] [info] [PluginUtils.h:36] Successfully loaded the plugin. -[2024-11-24 19:46:56.416] [info] [DefaultQuantumPlatform.cpp:87] Backend string is braket;machine;arn:aws:braket:::device/quantum-simulator/amazon/sv1 -[2024-11-24 19:46:56.416] [info] [DefaultQuantumPlatform.cpp:104] Config file path = /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../targets/braket.yml -[2024-11-24 19:46:56.416] [info] [DefaultQuantumPlatform.cpp:122] Default platform QPU subtype name: remote_rest -[2024-11-24 19:46:56.416] [info] [BaseRemoteRESTQPU.h:212] Remote REST platform is targeting braket;machine;arn:aws:braket:::device/quantum-simulator/amazon/sv1. -[2024-11-24 19:46:56.416] [info] [BaseRemoteRESTQPU.h:269] Config file path = /usr/local/cudaq/cudaq/mlir/_mlir_libs/../../../targets/braket.yml -[2024-11-24 19:46:56.416] [info] [BaseRemoteRESTQPU.h:279] Appending lowering pipeline: func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0},expand-control-veqs,canonicalize,combine-quantum-alloc),symbol-dce -[2024-11-24 19:46:56.417] [info] [BaseRemoteRESTQPU.h:285] Set codegen translation: qasm2 -[2024-11-24 19:46:56.417] [info] [BraketServerHelper.cpp:54] Initializing Amazon Braket backend. -[2024-11-24 19:46:56.417] [info] [BraketServerHelper.cpp:60] Running on device arn:aws:braket:::device/quantum-simulator/amazon/sv1 -[2024-11-24 19:46:56.417] [info] [BaseRemoteRESTQPU.h:324] Retrieving executor with name braket -[2024-11-24 19:46:56.417] [info] [BaseRemoteRESTQPU.h:326] Is this executor registered? true -[2024-11-24 19:46:56.438] [info] [quantum_platform.cpp:37] external caller setting the platform. -[2024-11-24 19:46:56.438] [info] [execution_manager.cpp:21] external caller clearing the execution manager. -[2024-11-24 19:46:56.438] [info] [BaseRemoteRESTQPU.h:195] Remote Rest QPU setting execution context to sample -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} -[2024-11-24 19:46:56.465] [info] [BaseRemoteRESTQPU.h:602] launching remote rest kernel (kernel) -[2024-11-24 19:46:56.466] [info] [cudaq.cpp:220] Replacing code for kernel kernel -[2024-11-24 19:46:56.466] [info] [BaseRemoteRESTQPU.h:430] Pass pipeline for kernel = cc-loop-unroll{allow-early-exit=0},canonicalize,func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=R1ToU3,U3ToRotations,CCZToCX,CRzToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz,SAdjToSZ},func.func(memtoreg{quantum=0},expand-control-veqs,canonicalize,combine-quantum-alloc),symbol-dce -// -----// IR Dump Before LoopUnroll (cc-loop-unroll) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before ConstPropComplex (const-prop-complex) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before CSE (cse) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before LiftArrayAlloc (lift-array-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before GlobalizeArrayValues (globalize-array-values) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before StatePreparation (state-prep) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before UnitarySynthesis (unitary-synthesis) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before ApplySpecialization (apply-op-specialization) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before ConvertToDirectCalls (indirect-to-direct-calls) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Inliner (inline) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before CheckKernelCalls (check-kernel-calls) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before MemToReg (memtoreg) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before LoopNormalize (cc-loop-normalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before LoopUnroll (cc-loop-unroll) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before UpdateRegisterNames (update-register-names) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before LowerToCFG (lower-to-cfg) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before MultiControlDecompositionPass (multicontrol-decomposition) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before DecompositionPass (decomposition) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before MemToReg (memtoreg) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before ExpandControlVeqs (expand-control-veqs) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before CombineQuantumAllocations (combine-quantum-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump After CombineQuantumAllocations (combine-quantum-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %c0_i64 = arith.constant 0 : i64 - %c3_i64 = arith.constant 3 : i64 - %c2_i64 = arith.constant 2 : i64 - %c1_i64 = arith.constant 1 : i64 - %0 = quake.alloca !quake.veq<4> - %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> - %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %3 : (!quake.ref) -> () - %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before SymbolDCE (symbol-dce) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %c0_i64 = arith.constant 0 : i64 - %c3_i64 = arith.constant 3 : i64 - %c2_i64 = arith.constant 2 : i64 - %c1_i64 = arith.constant 1 : i64 - %0 = quake.alloca !quake.veq<4> - %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> - %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %3 : (!quake.ref) -> () - %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %c0_i64 = arith.constant 0 : i64 - %c3_i64 = arith.constant 3 : i64 - %c2_i64 = arith.constant 2 : i64 - %c1_i64 = arith.constant 1 : i64 - %0 = quake.alloca !quake.veq<4> - %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> - %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %3 : (!quake.ref) -> () - %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump After Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before CSE (cse) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before MemToReg (memtoreg) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before LoopUnroll (cc-loop-unroll) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before LiftArrayAlloc (lift-array-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before GlobalizeArrayValues (globalize-array-values) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before StatePreparation (state-prep) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before GetConcreteMatrix (get-concrete-matrix) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before UnitarySynthesis (unitary-synthesis) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before SymbolDCE (symbol-dce) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before CSE (cse) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before MultiControlDecompositionPass (multicontrol-decomposition) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before DecompositionPass (decomposition) ('builtin.module' operation) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before ExpandControlVeqs (expand-control-veqs) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before CombineQuantumAllocations (combine-quantum-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump After CombineQuantumAllocations (combine-quantum-alloc) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %c0_i64 = arith.constant 0 : i64 - %c3_i64 = arith.constant 3 : i64 - %c2_i64 = arith.constant 2 : i64 - %c1_i64 = arith.constant 1 : i64 - %0 = quake.alloca !quake.veq<4> - %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> - %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %3 : (!quake.ref) -> () - %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before CombineMeasurements (combine-measurements) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { - %c0_i64 = arith.constant 0 : i64 - %c3_i64 = arith.constant 3 : i64 - %c2_i64 = arith.constant 2 : i64 - %c1_i64 = arith.constant 1 : i64 - %0 = quake.alloca !quake.veq<4> - %1 = quake.subveq %0, %c0_i64, %c3_i64 : (!quake.veq<4>, i64, i64) -> !quake.veq<4> - %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %3 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %3 : (!quake.ref) -> () - %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump After CombineMeasurements (combine-measurements) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", output_names = "[[[0,[0,\220\22]],[1,[1,\221\22]],[2,[2,\222\22]]]]"} { - %c2_i64 = arith.constant 2 : i64 - %c1_i64 = arith.constant 1 : i64 - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump Before Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", output_names = "[[[0,[0,\220\22]],[1,[1,\221\22]],[2,[2,\222\22]]]]"} { - %c2_i64 = arith.constant 2 : i64 - %c1_i64 = arith.constant 1 : i64 - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[%c1_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[%c2_i64] : (!quake.veq<4>, i64) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -// -----// IR Dump After Canonicalizer (canonicalize) ('func.func' operation: @__nvqpp__mlirgen__kernel) //----- // -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", output_names = "[[[0,[0,\220\22]],[1,[1,\221\22]],[2,[2,\222\22]]]]"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} - - -NEW MODULE: -module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { - func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint", output_names = "[[[0,[0,\220\22]],[1,[1,\221\22]],[2,[2,\222\22]]]]"} { - %0 = quake.alloca !quake.veq<4> - %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref - quake.x %1 : (!quake.ref) -> () - %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref - quake.x %2 : (!quake.ref) -> () - %measOut = quake.mz %0 : (!quake.veq<4>) -> !cc.stdvec - return - } -} -CODE STR: // Code generated by NVIDIA's nvq++ compiler -OPENQASM 2.0; - -include "qelib1.inc"; - -qreg var0[4]; -x var0[1]; -x var0[2]; -creg var3[4]; -measure var0 -> var3; - -Results: {"additionalMetadata":{"action":{"braketSchemaHeader":{"name":"braket.ir.openqasm.program","version":"1"},"inputs":{},"source":"// Code generated by NVIDIA's nvq++ compiler\nOPENQASM 2.0;\n\n\n\nqreg var0[4];\nx var0[1];\nx var0[2];\ncreg var3[4];\nmeasure var0 -> var3;\n"},"simulatorMetadata":{"braketSchemaHeader":{"name":"braket.task_result.simulator_metadata","version":"1"},"executionDuration":2}},"braketSchemaHeader":{"name":"braket.task_result.gate_model_task_result","version":"1"},"measuredQubits":[0,1,2,3],"measurements":[[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0]],"resultTypes":[],"taskMetadata":{"braketSchemaHeader":{"name":"braket.task_result.task_metadata","version":"1"},"createdAt":"2024-11-23T19:16:08.872Z","deviceId":"arn:aws:braket:::device/quantum-simulator/amazon/sv1","deviceParameters":{"braketSchemaHeader":{"name":"braket.device_schema.simulators.gate_model_simulator_device_parameters","version":"1"},"paradigmParameters":{"braketSchemaHeader":{"name":"braket.device_schema.gate_model_parameters","version":"1"},"disableQubitRewiring":false,"qubitCount":4}},"endedAt":"2024-11-23T19:16:10.138Z","id":"arn:aws:braket:us-east-1:783764578061:quantum-task/8bad9d49-b546-4ed8-8517-1b23c1eb929e","shots":100,"status":"COMPLETED"}} -[2024-11-24 19:46:56.483] [info] [BraketServerHelper.cpp:130] Qubit 1 Result 0 Name q1 -[2024-11-24 19:46:56.483] [info] [BraketServerHelper.cpp:130] Qubit 2 Result 1 Name q2 -COUNTS: -0110: 100 -Register name: __global__ -Sequential data: __global__ -{ 11:100 } - From af14f1b9feb90f4367f0724d5649f01f8d50229b Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 25 Nov 2024 14:44:54 -0800 Subject: [PATCH 35/47] Update translate tests Signed-off-by: Anna Gringauze --- program.py | 40 ------------ test/Translate/openqasm2_adj_rotations.cpp | 4 +- test/Translate/openqasm2_loop.cpp | 4 +- test/Translate/openqasm2_vector.cpp | 4 +- .../translate_openqasm2_adj_rotations.cpp | 61 ------------------- 5 files changed, 9 insertions(+), 104 deletions(-) delete mode 100644 program.py delete mode 100644 test/Translate/translate_openqasm2_adj_rotations.cpp diff --git a/program.py b/program.py deleted file mode 100644 index 6ab7054bf5..0000000000 --- a/program.py +++ /dev/null @@ -1,40 +0,0 @@ -# ============================================================================ # -# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. # -# All rights reserved. # -# # -# This source code and the accompanying materials are made available under # -# the terms of the Apache License 2.0 which accompanies this distribution. # -# ============================================================================ # - -import cudaq - -def test_multiple_measurement(): - device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" - cudaq.set_target("braket", emulate=True, machine=device_arn) - - @cudaq.kernel - def kernel(): - qubits = cudaq.qvector(2) - h(qubits[0]) - mz(qubits[0]) - mz(qubits[1]) - - print(kernel) - cudaq.sample(kernel, shots_count=100).dump() - -test_multiple_measurement() - -def test_qvector_slicing(): - device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" - cudaq.set_target("braket", emulate=True, machine=device_arn) - - @cudaq.kernel - def kernel(): - q = cudaq.qvector(4) - x(q.front(2)) - mz(q) - - print(kernel) - cudaq.sample(kernel, shots_count=100).dump() - -#test_qvector_slicing() \ No newline at end of file diff --git a/test/Translate/openqasm2_adj_rotations.cpp b/test/Translate/openqasm2_adj_rotations.cpp index b9cbb2bac6..f443616111 100644 --- a/test/Translate/openqasm2_adj_rotations.cpp +++ b/test/Translate/openqasm2_adj_rotations.cpp @@ -6,7 +6,9 @@ * the terms of the Apache License 2.0 which accompanies this distribution. * ******************************************************************************/ -// RUN: cudaq-quake %s | cudaq-translate --convert-to=openqasm2 | FileCheck %s +// clang-format off +// RUN: cudaq-quake %s | cudaq-opt --decomposition=enable-patterns="RxAdjToRx,RyAdjToRy,RzAdjToRz" | cudaq-translate --convert-to=openqasm2 | FileCheck %s +// clang-format on #include #include diff --git a/test/Translate/openqasm2_loop.cpp b/test/Translate/openqasm2_loop.cpp index d2d920e00b..b9f04f5a7c 100644 --- a/test/Translate/openqasm2_loop.cpp +++ b/test/Translate/openqasm2_loop.cpp @@ -6,7 +6,9 @@ * the terms of the Apache License 2.0 which accompanies this distribution. * ******************************************************************************/ -// RUN: cudaq-quake %s | cudaq-translate --convert-to=openqasm2 | FileCheck %s +// clang-format off +// RUN: cudaq-quake %s | | cudaq-opt --unrolling-pipeline | cudaq-translate --convert-to=openqasm2 | FileCheck %s +// clang-format on #include #include diff --git a/test/Translate/openqasm2_vector.cpp b/test/Translate/openqasm2_vector.cpp index cb47358b95..5e7c854730 100644 --- a/test/Translate/openqasm2_vector.cpp +++ b/test/Translate/openqasm2_vector.cpp @@ -6,7 +6,9 @@ * the terms of the Apache License 2.0 which accompanies this distribution. * ******************************************************************************/ -// RUN: cudaq-quake %s | cudaq-translate --convert-to=openqasm2 | FileCheck %s +// clang-format off +// RUN: cudaq-quake %s | cudaq-opt -canonicalize -cse -lift-array-alloc -globalize-array-values -state-prep | cudaq-translate --convert-to=openqasm2 | FileCheck %s +// clang-format on #include #include diff --git a/test/Translate/translate_openqasm2_adj_rotations.cpp b/test/Translate/translate_openqasm2_adj_rotations.cpp deleted file mode 100644 index b9cbb2bac6..0000000000 --- a/test/Translate/translate_openqasm2_adj_rotations.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * - * All rights reserved. * - * * - * This source code and the accompanying materials are made available under * - * the terms of the Apache License 2.0 which accompanies this distribution. * - ******************************************************************************/ - -// RUN: cudaq-quake %s | cudaq-translate --convert-to=openqasm2 | FileCheck %s - -#include -#include -#include - -struct kernel { - void operator()() __qpu__ { - double theta = 0.67; - cudaq::qvector qubits(6); - - x(qubits[5]); - h(qubits[4], qubits[5]); - rx(theta, qubits[4]); - - x(qubits[3]); - h(qubits[2], qubits[3]); - ry(theta, qubits[2]); - - x(qubits[1]); - h(qubits[0], qubits[1]); - rz(theta, qubits[0]); - - mz(qubits); - } -}; - - -int main() { - auto counts = cudaq::sample(kernel{}); - counts.dump(); -} - -// CHECK: // Code generated by NVIDIA's nvq++ compiler -// CHECK: OPENQASM 2.0; - -// CHECK: include "qelib1.inc"; - -// CHECK: gate ZN6kernelclEv(param0) { -// CHECK: } - -// CHECK: qreg var0[6]; -// CHECK: x var0[5]; -// CHECK: ch var0[4], var0[5]; -// CHECK: rx(-6.700000e-01) var0[4]; -// CHECK: x var0[3]; -// CHECK: ch var0[2], var0[3]; -// CHECK: ry(-6.700000e-01) var0[2]; -// CHECK: x var0[1]; -// CHECK: ch var0[0], var0[1]; -// CHECK: rz(-6.700000e-01) var0[0]; -// CHECK: creg var7[6]; -// CHECK: measure var0 -> var7; From 41d0aaa566721eef9dceeeb913a3b0874ae1322d Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 10:36:24 -0800 Subject: [PATCH 36/47] support multimple qubit measurements Signed-off-by: Anna Gringauze --- lib/Optimizer/CodeGen/Pipelines.cpp | 5 +- .../Transforms/CombineMeasurements.cpp | 192 ++++++++++++++---- program.py | 67 ++++++ .../cudaq/platform/py_alt_launch_kernel.cpp | 27 +++ .../default/rest/helpers/braket/braket.yml | 2 +- test/Quake/combine_measurements.qke | 65 ++++-- 6 files changed, 303 insertions(+), 55 deletions(-) create mode 100644 program.py diff --git a/lib/Optimizer/CodeGen/Pipelines.cpp b/lib/Optimizer/CodeGen/Pipelines.cpp index fbbc6960ff..95f8debb76 100644 --- a/lib/Optimizer/CodeGen/Pipelines.cpp +++ b/lib/Optimizer/CodeGen/Pipelines.cpp @@ -45,10 +45,6 @@ void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) { pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); pm.addNestedPass(createClassicalMemToReg()); - pm.addNestedPass(createExpandControlVeqs()); - pm.addNestedPass(createCombineQuantumAllocations()); - pm.addNestedPass(createCombineMeasurements()); - pm.addNestedPass(createCanonicalizerPass()); pm.addPass(createSymbolDCEPass()); } @@ -61,5 +57,6 @@ void cudaq::opt::addPipelineTranslateToIQMJson(PassManager &pm) { pm.addNestedPass(createLowerToCFGPass()); pm.addNestedPass(createQuakeAddDeallocs()); pm.addNestedPass(createCombineQuantumAllocations()); + pm.addPass(createCanonicalizerPass()); pm.addPass(createCSEPass()); } diff --git a/lib/Optimizer/Transforms/CombineMeasurements.cpp b/lib/Optimizer/Transforms/CombineMeasurements.cpp index 988280bcc1..7e0f74948f 100644 --- a/lib/Optimizer/Transforms/CombineMeasurements.cpp +++ b/lib/Optimizer/Transforms/CombineMeasurements.cpp @@ -12,13 +12,13 @@ #include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h" #include "cudaq/Optimizer/Dialect/Quake/QuakeTypes.h" #include "cudaq/Optimizer/Transforms/Passes.h" -#include "nlohmann/json.hpp" #include "llvm/Support/Debug.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "mlir/Transforms/Passes.h" +#include "nlohmann/json.hpp" namespace cudaq::opt { #define GEN_PASS_DEF_COMBINEMEASUREMENTS @@ -31,65 +31,178 @@ using namespace mlir; namespace { -class ExtendMeasurePattern : public OpRewritePattern { +struct Analysis { + using OutputNamesType = + std::map>; + + Analysis() = default; + Analysis(const Analysis &) = delete; + Analysis(Analysis &&) = delete; + Analysis &operator=(const Analysis &) = delete; + + mlir::DenseMap measurements; + OutputNamesType resultQubitVals; + quake::MzOp lastMeasurement; + + bool empty() const { return measurements.empty(); } + + LogicalResult analyze(func::FuncOp func) { + quake::AllocaOp qalloc; + std::size_t currentOffset = 0; + + for (auto &block : func.getRegion()) { + for (auto &op : block) { + if (auto alloc = dyn_cast_or_null(&op)) { + if (qalloc) + return op.emitError("Multiple qalloc statements found"); + + qalloc = alloc; + } else if (auto measure = dyn_cast_or_null(&op)) { + if (!measure.use_empty()) + return measure.emitError("Measurements with uses are not supported"); + + auto veqOp = measure.getOperand(0); + auto ty = veqOp.getType(); + + std::size_t size = 0; + if (auto veqTy = dyn_cast(ty)) + size = 1; + else if (auto veqTy = dyn_cast(ty)) { + size = veqTy.getSize(); + if (size == 0) + return op.emitError("Unknown measurement size"); + } + + measurements[measure.getMeasOut()] = currentOffset; + lastMeasurement = measure; + currentOffset += size; + } + } + } + + return success(); + } +}; + +class ExtendQubitMeasurePattern : public OpRewritePattern { + using OutputNamesType = + std::map>; + +public: + using OpRewritePattern::OpRewritePattern; + + explicit ExtendQubitMeasurePattern(MLIRContext *ctx, Analysis &analysis) + : OpRewritePattern(ctx), analysis(analysis) {} + + // Replace a pattern such as: + // ``` + // %0 = ...: !quake.veq<2> + // %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref + // %measOut = quake.mz %1 : (!quake.ref) -> !quake.measure + // ``` + // with: + // ``` + // %1 = ... : !quake.veq<4> + // %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec + // ``` + // And collect output names information: `"[[[0,[1,"q0"]],[1,[2,"q1"]]]]"` + LogicalResult matchAndRewrite(quake::MzOp measure, + PatternRewriter &rewriter) const override { + + auto veqOp = measure.getOperand(0); + if (auto extract = veqOp.getDefiningOp()) { + auto veq = extract.getVeq(); + std::size_t idx; + + if (extract.hasConstantIndex()) + idx = extract.getConstantIndex(); + else if (auto cst = + extract.getIndex().getDefiningOp()) + idx = static_cast(cst.value()); + else + return extract.emitError("Non-constant index in ExtractRef"); + + auto offset = idx + analysis.measurements[measure.getMeasOut()]; + analysis.resultQubitVals[offset] = + std::make_pair(idx, std::to_string(idx)); + + auto resultType = cudaq::cc::StdvecType::get(measure.getType(0)); + if (measure == analysis.lastMeasurement) + rewriter.replaceOpWithNewOp(measure, TypeRange{resultType}, + ValueRange{veq}, + measure.getRegisterNameAttr()); + else + rewriter.eraseOp(measure); + } + + return failure(); + } + +private: + Analysis &analysis; +}; + +class ExtendVeqMeasurePattern : public OpRewritePattern { using OutputNamesType = std::map>; public: using OpRewritePattern::OpRewritePattern; - explicit ExtendMeasurePattern(MLIRContext *ctx, - OutputNamesType &resultQubitVals) - : OpRewritePattern(ctx), resultQubitVals(resultQubitVals) {} + explicit ExtendVeqMeasurePattern(MLIRContext *ctx, Analysis &analysis) + : OpRewritePattern(ctx), analysis(analysis) {} // Replace a pattern such as: // ``` - // func.func @kernel() attributes {"cudaq-entrypoint"} { // %1 = ... : !quake.veq<4> - // %2 = quake.subveq %1, %c2, %c3 : (!quake.veq<4>, i32, i32) -> + // %2 = quake.subveq %1, %c1, %c2 : (!quake.veq<4>, i32, i32) -> // !quake.veq<2> // %measOut = quake.mz %2 : (!quake.veq<2>) -> !cc.stdvec - // } // ``` // with: // ``` - // func.func @kernel() attributes {"cudaq-entrypoint", ["output_names", - // "[[[0,[1,\22q0\22]],[1,[2,\22q1\22]]]]"]} { // %1 = ... : !quake.veq<4> // %measOut = quake.mz %1 : (!quake.veq<4>) -> !cc.stdvec - // } // ``` + // And collect output names information: `"[[[0,[1,"q0"]],[1,[2,"q1"]]]]"` LogicalResult matchAndRewrite(quake::MzOp measure, PatternRewriter &rewriter) const override { - if (!measure.use_empty()) { - measure.emitError("Only measures with no uses are supported"); - return failure(); - } auto veqOp = measure.getOperand(0); if (auto subveq = veqOp.getDefiningOp()) { Value lowOp = subveq.getLow(); Value highOp = subveq.getHigh(); - if (auto constLow = lowOp.getDefiningOp()) { - auto low = static_cast(constLow.value()); - if (auto constHigh = highOp.getDefiningOp()) { - auto high = static_cast(constHigh.value()); - for (std::size_t i = low; i <= high; i++) { - // Note: regname is ignored for OpenQasm2 targets - resultQubitVals[i - low] = std::make_pair(i, std::to_string(i)); - } - rewriter.replaceOpWithNewOp( - measure, measure.getResultTypes(), subveq.getVeq()); - return success(); - } + + auto constLow = lowOp.getDefiningOp(); + if (!constLow) + return subveq.emitError("Non-constant low index in subveq"); + auto constHigh = highOp.getDefiningOp(); + if (!constHigh) + return subveq.emitError("Non-constant high index in subveq"); + + auto low = static_cast(constLow.value()); + auto high = static_cast(constHigh.value()); + + for (std::size_t i = low; i <= high; i++) { + auto start = analysis.measurements[measure.getMeasOut()]; + auto offset = i - low + start; + analysis.resultQubitVals[offset] = std::make_pair(i, std::to_string(i)); } + if (measure == analysis.lastMeasurement) + rewriter.replaceOpWithNewOp( + measure, measure.getResultTypes(), ValueRange{subveq.getVeq()}, + measure.getRegisterNameAttr()); + else + rewriter.eraseOp(measure); + + return success(); } return failure(); } private: - OutputNamesType &resultQubitVals; + Analysis &analysis; }; class CombineMeasurementsPass @@ -109,18 +222,29 @@ class CombineMeasurementsPass LLVM_DEBUG(llvm::dbgs() << "Function before combining measurements:\n" << func << "\n\n"); + // Analyze the function to find all qubit mappings. + Analysis analysis; + if (failed(analysis.analyze(func))) { + func.emitOpError("Combining measurements failed"); + signalPassFailure(); + } + + if (analysis.empty()) + return; + + // Extend measurement into one last full measurement. RewritePatternSet patterns(ctx); - OutputNamesType resultQubitVals; - patterns.insert(ctx, resultQubitVals); + patterns.insert( + ctx, analysis); if (failed(applyPatternsAndFoldGreedily(func.getOperation(), std::move(patterns)))) { - func.emitOpError("combining measurements failed"); + func.emitOpError("Combining measurements failed"); signalPassFailure(); } - // TODO: move measOut to the end of the func (see delayMeasurements?) - if (!resultQubitVals.empty()) { - nlohmann::json resultQubitJSON{resultQubitVals}; + // Add output names mapping attribute. + if (!analysis.resultQubitVals.empty()) { + nlohmann::json resultQubitJSON{analysis.resultQubitVals}; func->setAttr(cudaq::opt::QIROutputNamesAttrName, builder.getStringAttr(resultQubitJSON.dump())); } diff --git a/program.py b/program.py new file mode 100644 index 0000000000..4be7c09c27 --- /dev/null +++ b/program.py @@ -0,0 +1,67 @@ +# ============================================================================ # +# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. # +# All rights reserved. # +# # +# This source code and the accompanying materials are made available under # +# the terms of the Apache License 2.0 which accompanies this distribution. # +# ============================================================================ # + +import cudaq +def test_multiple_measurement(): + device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" + cudaq.set_target("braket", emulate=True, machine=device_arn) + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + h(qubits[0]) + mz(qubits[0]) + mz(qubits[1]) + + print(kernel) + cudaq.sample(kernel, shots_count=100).dump() + +#test_multiple_measurement() + +def test_qvector_slicing(): + device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" + cudaq.set_target("braket", emulate=True, machine=device_arn) + + @cudaq.kernel + def kernel(): + q = cudaq.qvector(4) + x(q.front(2)) + mz(q) + + print(kernel) + cudaq.sample(kernel, shots_count=100).dump() + +#test_qvector_slicing() + +def test_mid_circuit_measurement(): + device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" + cudaq.set_target("braket", emulate=True, machine=device_arn) + @cudaq.kernel + def simple(): + q = cudaq.qvector(2) + h(q[0]) + if mz(q[0]): + x(q[1]) + mz(q) + + ## error: 'cf.cond_br' op unable to translate op to OpenQASM 2.0 + cudaq.sample(simple, shots_count=100).dump() + +test_mid_circuit_measurement() + +# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { +# func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { +# %0 = quake.alloca !quake.veq<2> +# %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref +# quake.h %1 : (!quake.ref) -> () +# %measOut = quake.mz %1 : (!quake.ref) -> !quake.measure +# %2 = quake.extract_ref %0[1] : (!quake.veq<2>) -> !quake.ref +# %measOut_0 = quake.mz %2 : (!quake.ref) -> !quake.measure +# return +# } +# } \ No newline at end of file diff --git a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp index 25edfdc8c6..dd542b73c0 100644 --- a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp +++ b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp @@ -641,6 +641,33 @@ std::string getASM(const std::string &name, MlirModule module, PassManager pm(context); pm.addPass(cudaq::opt::createLambdaLiftingPass()); + // Run most of the passes from hardware pipelines. + + pm.addPass(createCanonicalizerPass()); + pm.addPass(createCSEPass()); + pm.addNestedPass(cudaq::opt::createClassicalMemToReg()); + pm.addPass(cudaq::opt::createLoopUnroll()); + pm.addPass(createCanonicalizerPass()); + pm.addNestedPass(cudaq::opt::createLiftArrayAlloc()); + pm.addPass(cudaq::opt::createGlobalizeArrayValues()); + pm.addPass(cudaq::opt::createStatePreparation()); + pm.addNestedPass(cudaq::opt::createGetConcreteMatrix()); + pm.addPass(cudaq::opt::createUnitarySynthesis()); + pm.addPass(cudaq::opt::createApplyOpSpecializationPass()); + cudaq::opt::addAggressiveEarlyInlining(pm); + pm.addPass(createSymbolDCEPass()); + pm.addPass(createCanonicalizerPass()); + pm.addPass(createCSEPass()); + pm.addNestedPass( + cudaq::opt::createMultiControlDecompositionPass()); + pm.addPass(cudaq::opt::createDecompositionPass( + {.enabledPatterns = {"SToR1", "TToR1", "R1ToU3", "U3ToRotations", + "CHToCX", "CCZToCX", "CRzToCX", "CRyToCX", "CRxToCX", + "CR1ToCX", "CCZToCX", "RxAdjToRx", "RyAdjToRy", + "RzAdjToRz"}})); + pm.addPass(createCanonicalizerPass()); + pm.addNestedPass(cudaq::opt::createExpandControlVeqs()); + pm.addNestedPass(cudaq::opt::createCombineQuantumAllocations()); cudaq::opt::addPipelineTranslateToOpenQASM(pm); if (disableMLIRthreading || enablePrintMLIREachPass) diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index f7a72c432b..66e485df1a 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -17,7 +17,7 @@ config: # Tell NVQ++ to generate glue code to set the target backend name gen-target-backend: true # Define the lowering pipeline - platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=SToR1,TToR1,R1ToU3,U3ToRotations,CHToCX,CCZToCX,CRzToCX,CRyToCX,CRxToCX,CR1ToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz}" + platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=SToR1,TToR1,R1ToU3,U3ToRotations,CHToCX,CCZToCX,CRzToCX,CRyToCX,CRxToCX,CR1ToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(expand-control-veqs,combine-quantum-alloc,canonicalize,combine-measurements)" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 # Additional passes to run after lowering to QUAKE diff --git a/test/Quake/combine_measurements.qke b/test/Quake/combine_measurements.qke index f3dfa77555..5ab41f7abe 100644 --- a/test/Quake/combine_measurements.qke +++ b/test/Quake/combine_measurements.qke @@ -7,7 +7,40 @@ // ========================================================================== // // RUN: cudaq-opt -combine-measurements -canonicalize %s | FileCheck %s + module { + func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<2> + %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref + %measOut = quake.mz %1 : (!quake.ref) -> !quake.measure + %2 = quake.extract_ref %0[1] : (!quake.veq<2>) -> !quake.ref + %measOut_0 = quake.mz %2 : (!quake.ref) -> !quake.measure + return + } + +// CHECK: func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[2,\[1,\\221\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<2> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<2>) -> !cc.stdvec +// CHECK: return +// CHECK: } + + func.func @mz_2bits_extract_cst_op_index() attributes {"cudaq-entrypoint"} { + %c1_i64 = arith.constant 1 : i64 + %c0_i64 = arith.constant 0 : i64 + %0 = quake.alloca !quake.veq<2> + %1 = quake.extract_ref %0[%c0_i64] : (!quake.veq<2>, i64) -> !quake.ref + %measOut = quake.mz %1 : (!quake.ref) -> !quake.measure + %2 = quake.extract_ref %0[%c1_i64] : (!quake.veq<2>, i64) -> !quake.ref + %measOut_0 = quake.mz %2 : (!quake.ref) -> !quake.measure + return + } + +// CHECK: func.func @mz_2bits_extract_cst_op_index() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[2,\[1,\\221\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<2> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<2>) -> !cc.stdvec +// CHECK: return +// CHECK: } + func.func @subveq_4_1() attributes {"cudaq-entrypoint"} { %c1_i64 = arith.constant 1 : i64 %0 = quake.alloca !quake.veq<4> @@ -16,11 +49,11 @@ module { return } -// CHECK: func.func @subveq_4_1() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\]\]\]}}"} { -// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> -// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec -// CHECK: return -// CHECK: } +// CHECK: func.func @subveq_4_1() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec +// CHECK: return +// CHECK: } func.func @subveq_4_2() attributes {"cudaq-entrypoint"} { %c1_i64 = arith.constant 1 : i64 @@ -31,11 +64,11 @@ module { return } -// CHECK: func.func @subveq_4_2() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\],\[1,\[2,\\222\\22\]\]\]\]}}"} { -// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> -// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec -// CHECK: return -// CHECK: } +// CHECK: func.func @subveq_4_2() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\],\[1,\[2,\\222\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec +// CHECK: return +// CHECK: } func.func @subveq_4_4() attributes {"cudaq-entrypoint"} { %c0_i64 = arith.constant 0 : i64 @@ -46,9 +79,9 @@ module { return } -// CHECK: func.func @subveq_4_4() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[1,\[1,\\221\\22\]\],\[2,\[2,\\222\\22\]\],\[3,\[3,\\223\\22\]\]\]\]}}"} { -// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> -// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec -// CHECK: return -// CHECK: } -} \ No newline at end of file +// CHECK: func.func @subveq_4_4() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[1,\[1,\\221\\22\]\],\[2,\[2,\\222\\22\]\],\[3,\[3,\\223\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec +// CHECK: return +// CHECK: } +} From bb1b72f9f42d05b4753f24ca9eca45cb714eb849 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 11:21:59 -0800 Subject: [PATCH 37/47] Added tests Signed-off-by: Anna Gringauze --- .../Transforms/CombineMeasurements.cpp | 12 ++-- program.py | 67 ------------------- python/tests/backends/test_braket.py | 53 +++++++++++++-- test/Quake/combine_measurements.qke | 16 +++++ 4 files changed, 72 insertions(+), 76 deletions(-) delete mode 100644 program.py diff --git a/lib/Optimizer/Transforms/CombineMeasurements.cpp b/lib/Optimizer/Transforms/CombineMeasurements.cpp index 7e0f74948f..7175c0530a 100644 --- a/lib/Optimizer/Transforms/CombineMeasurements.cpp +++ b/lib/Optimizer/Transforms/CombineMeasurements.cpp @@ -12,13 +12,13 @@ #include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h" #include "cudaq/Optimizer/Dialect/Quake/QuakeTypes.h" #include "cudaq/Optimizer/Transforms/Passes.h" +#include "nlohmann/json.hpp" #include "llvm/Support/Debug.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "mlir/Transforms/Passes.h" -#include "nlohmann/json.hpp" namespace cudaq::opt { #define GEN_PASS_DEF_COMBINEMEASUREMENTS @@ -58,8 +58,10 @@ struct Analysis { qalloc = alloc; } else if (auto measure = dyn_cast_or_null(&op)) { - if (!measure.use_empty()) - return measure.emitError("Measurements with uses are not supported"); + if (!measure.use_empty()) { + measure.emitWarning("Measurements with uses are not supported"); + return success(); + } auto veqOp = measure.getOperand(0); auto ty = veqOp.getType(); @@ -131,7 +133,7 @@ class ExtendQubitMeasurePattern : public OpRewritePattern { rewriter.replaceOpWithNewOp(measure, TypeRange{resultType}, ValueRange{veq}, measure.getRegisterNameAttr()); - else + else if (measure.use_empty()) rewriter.eraseOp(measure); } @@ -192,7 +194,7 @@ class ExtendVeqMeasurePattern : public OpRewritePattern { rewriter.replaceOpWithNewOp( measure, measure.getResultTypes(), ValueRange{subveq.getVeq()}, measure.getRegisterNameAttr()); - else + else if (measure.use_empty()) rewriter.eraseOp(measure); return success(); diff --git a/program.py b/program.py deleted file mode 100644 index 4be7c09c27..0000000000 --- a/program.py +++ /dev/null @@ -1,67 +0,0 @@ -# ============================================================================ # -# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. # -# All rights reserved. # -# # -# This source code and the accompanying materials are made available under # -# the terms of the Apache License 2.0 which accompanies this distribution. # -# ============================================================================ # - -import cudaq -def test_multiple_measurement(): - device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" - cudaq.set_target("braket", emulate=True, machine=device_arn) - - @cudaq.kernel - def kernel(): - qubits = cudaq.qvector(2) - h(qubits[0]) - mz(qubits[0]) - mz(qubits[1]) - - print(kernel) - cudaq.sample(kernel, shots_count=100).dump() - -#test_multiple_measurement() - -def test_qvector_slicing(): - device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" - cudaq.set_target("braket", emulate=True, machine=device_arn) - - @cudaq.kernel - def kernel(): - q = cudaq.qvector(4) - x(q.front(2)) - mz(q) - - print(kernel) - cudaq.sample(kernel, shots_count=100).dump() - -#test_qvector_slicing() - -def test_mid_circuit_measurement(): - device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" - cudaq.set_target("braket", emulate=True, machine=device_arn) - @cudaq.kernel - def simple(): - q = cudaq.qvector(2) - h(q[0]) - if mz(q[0]): - x(q[1]) - mz(q) - - ## error: 'cf.cond_br' op unable to translate op to OpenQASM 2.0 - cudaq.sample(simple, shots_count=100).dump() - -test_mid_circuit_measurement() - -# module attributes {quake.mangled_name_map = {__nvqpp__mlirgen__kernel = "__nvqpp__mlirgen__kernel_PyKernelEntryPointRewrite"}} { -# func.func @__nvqpp__mlirgen__kernel() attributes {"cudaq-entrypoint"} { -# %0 = quake.alloca !quake.veq<2> -# %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref -# quake.h %1 : (!quake.ref) -> () -# %measOut = quake.mz %1 : (!quake.ref) -> !quake.measure -# %2 = quake.extract_ref %0[1] : (!quake.veq<2>) -> !quake.ref -# %measOut_0 = quake.mz %2 : (!quake.ref) -> !quake.measure -# return -# } -# } \ No newline at end of file diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 4c7703cfab..b0b6cbc356 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -302,6 +302,37 @@ def kernel(): counts = cudaq.sample(kernel, shots_count=100) assert len(counts) == 1 assert "11" in counts + +def test_kernel_two_subveqs(): + + @cudaq.kernel + def kernel(): + qreg = cudaq.qvector(4) + x(qreg[1]) + x(qreg[2]) + v = qreg[0:2] + v = qreg[2:3] + mz(v) + + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 1 + assert "011" in counts + +def test_kernel_qubit_subveq(): + + @cudaq.kernel + def kernel(): + qreg = cudaq.qvector(4) + x(qreg[1]) + x(qreg[2]) + v = qreg[0:2] + v = qreg[2] + mz(v) + + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 1 + assert "011" in counts + def test_multiple_measurement(): @@ -312,10 +343,24 @@ def kernel(): mz(qubits[0]) mz(qubits[1]) - with pytest.raises(RuntimeError) as e: - cudaq.sample(kernel, shots_count=100).dump() - assert "cannot declare bit register. Only 1 bit register(s) is/are supported" in repr( - e) + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 2 + assert "00" in counts + assert "10" in counts + +def test_multiple_measurement_non_consecutive(): + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(3) + x(qubits[0]) + x(qubits[2]) + mz(qubits[0]) + mz(qubits[2]) + + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 1 + assert "11" in counts def test_qvector_slicing(): diff --git a/test/Quake/combine_measurements.qke b/test/Quake/combine_measurements.qke index 5ab41f7abe..24bc00e3f4 100644 --- a/test/Quake/combine_measurements.qke +++ b/test/Quake/combine_measurements.qke @@ -9,6 +9,7 @@ // RUN: cudaq-opt -combine-measurements -canonicalize %s | FileCheck %s module { + func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint"} { %0 = quake.alloca !quake.veq<2> %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref @@ -39,6 +40,21 @@ module { // CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<2> // CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<2>) -> !cc.stdvec // CHECK: return +// CHECK: } + + func.func @mz_2bits_extract_non_consecutive() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<3> + %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref + %measOut = quake.mz %1 : (!quake.ref) -> !quake.measure + %2 = quake.extract_ref %0[2] : (!quake.veq<2>) -> !quake.ref + %measOut_0 = quake.mz %2 : (!quake.ref) -> !quake.measure + return + } + +// CHECK: func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[2,\[1,\\222\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<3> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<3>) -> !cc.stdvec +// CHECK: return // CHECK: } func.func @subveq_4_1() attributes {"cudaq-entrypoint"} { From 208102b4a732307b76f3a4048926ca56a7ef6f18 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 11:26:21 -0800 Subject: [PATCH 38/47] Address CR comments Signed-off-by: Anna Gringauze --- python/runtime/cudaq/platform/py_alt_launch_kernel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp index dd542b73c0..4deefa3afb 100644 --- a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp +++ b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp @@ -561,7 +561,7 @@ MlirModule synthesizeKernel(const std::string &name, MlirModule module, pm.addNestedPass(cudaq::opt::createExpandMeasurementsPass()); pm.addNestedPass(cudaq::opt::createClassicalMemToReg()); pm.addNestedPass(createCanonicalizerPass()); - pm.addNestedPass(cudaq::opt::createLoopNormalize()); + pm.addPass(cudaq::opt::createLoopNormalize()); pm.addPass(cudaq::opt::createLoopUnroll()); pm.addNestedPass(createCanonicalizerPass()); DefaultTimingManager tm; From 4a780b04c79f5be591f9264076f200954f860363 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 11:52:22 -0800 Subject: [PATCH 39/47] Address CR comments and remove printing Signed-off-by: Anna Gringauze --- .../Transforms/CombineMeasurements.cpp | 21 ++++++++----------- runtime/common/BaseRemoteRESTQPU.h | 5 +---- test/Translate/openqasm2_loop.cpp | 2 +- test/Translate/openqasm2_vector.cpp | 2 +- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/lib/Optimizer/Transforms/CombineMeasurements.cpp b/lib/Optimizer/Transforms/CombineMeasurements.cpp index 7175c0530a..1dd768425c 100644 --- a/lib/Optimizer/Transforms/CombineMeasurements.cpp +++ b/lib/Optimizer/Transforms/CombineMeasurements.cpp @@ -31,10 +31,16 @@ using namespace mlir; namespace { -struct Analysis { - using OutputNamesType = - std::map>; +// After combine-quantum-alloc, we have one top allocation per function. +// The following type is used to store qubit mapping from result qubit +// index to the actual qubit index and register name. +// map[result] --> [qb,regName] +// Note: register name is currently not used in `OpenQasm2` backends, +// so we supply a bogus name. +using OutputNamesType = + std::map>; +struct Analysis { Analysis() = default; Analysis(const Analysis &) = delete; Analysis(Analysis &&) = delete; @@ -87,9 +93,6 @@ struct Analysis { }; class ExtendQubitMeasurePattern : public OpRewritePattern { - using OutputNamesType = - std::map>; - public: using OpRewritePattern::OpRewritePattern; @@ -145,9 +148,6 @@ class ExtendQubitMeasurePattern : public OpRewritePattern { }; class ExtendVeqMeasurePattern : public OpRewritePattern { - using OutputNamesType = - std::map>; - public: using OpRewritePattern::OpRewritePattern; @@ -210,9 +210,6 @@ class ExtendVeqMeasurePattern : public OpRewritePattern { class CombineMeasurementsPass : public cudaq::opt::impl::CombineMeasurementsBase< CombineMeasurementsPass> { - using OutputNamesType = - std::map>; - public: using CombineMeasurementsBase::CombineMeasurementsBase; diff --git a/runtime/common/BaseRemoteRESTQPU.h b/runtime/common/BaseRemoteRESTQPU.h index 7cf42b3680..fba54a2da7 100644 --- a/runtime/common/BaseRemoteRESTQPU.h +++ b/runtime/common/BaseRemoteRESTQPU.h @@ -564,10 +564,7 @@ class BaseRemoteRESTQPU : public cudaq::QPU { throw std::runtime_error("Could not successfully translate to " + codegenTranslation + "."); } - // TODO: see if modules are new here? - std::cout << "NEW MODULE: " << std::endl; - moduleOpI.dump(); - std::cout << "CODE STR: " << codeStr << std::endl; + // Form an output_names mapping from codeStr nlohmann::json j = formOutputNames(codegenTranslation, moduleOpI, codeStr); diff --git a/test/Translate/openqasm2_loop.cpp b/test/Translate/openqasm2_loop.cpp index b9f04f5a7c..2a956d3ad1 100644 --- a/test/Translate/openqasm2_loop.cpp +++ b/test/Translate/openqasm2_loop.cpp @@ -7,7 +7,7 @@ ******************************************************************************/ // clang-format off -// RUN: cudaq-quake %s | | cudaq-opt --unrolling-pipeline | cudaq-translate --convert-to=openqasm2 | FileCheck %s +// RUN: cudaq-quake %s | cudaq-opt --unrolling-pipeline | cudaq-translate --convert-to=openqasm2 | FileCheck %s // clang-format on #include diff --git a/test/Translate/openqasm2_vector.cpp b/test/Translate/openqasm2_vector.cpp index 5e7c854730..724d54a472 100644 --- a/test/Translate/openqasm2_vector.cpp +++ b/test/Translate/openqasm2_vector.cpp @@ -7,7 +7,7 @@ ******************************************************************************/ // clang-format off -// RUN: cudaq-quake %s | cudaq-opt -canonicalize -cse -lift-array-alloc -globalize-array-values -state-prep | cudaq-translate --convert-to=openqasm2 | FileCheck %s +// RUN: cudaq-quake %s | cudaq-opt -canonicalize -cse -lift-array-alloc -globalize-array-values -state-prep | cudaq-translate --convert-to=openqasm2 | FileCheck %s // clang-format on #include From 5af0c8d696395cd1136f255b48a0d6f766bb4905 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 12:48:08 -0800 Subject: [PATCH 40/47] Address CR comments and remove printing Signed-off-by: Anna Gringauze --- lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp | 3 +- .../Transforms/DecompositionPatterns.cpp | 29 ------------------- python/cudaq/kernel/ast_bridge.py | 1 - .../cudaq/platform/py_alt_launch_kernel.cpp | 14 ++++----- python/tests/backends/test_braket.py | 6 +++- .../rest/helpers/braket/BraketExecutor.cpp | 8 +---- .../default/rest/helpers/braket/braket.yml | 2 -- 7 files changed, 15 insertions(+), 48 deletions(-) diff --git a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp index 45e290b932..c5b98642c7 100644 --- a/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp +++ b/lib/Optimizer/CodeGen/TranslateToOpenQASM.cpp @@ -23,12 +23,13 @@ using namespace cudaq; //===----------------------------------------------------------------------===// // Helper functions //===----------------------------------------------------------------------===// + /// Translates operation names into OpenQASM gate names static LogicalResult translateOperatorName(quake::OperatorInterface optor, StringRef &name) { StringRef qkeName = optor->getName().stripDialect(); if (optor.getControls().size() == 0) { - name = StringSwitch(qkeName).Default(qkeName); + name = StringSwitch(qkeName).Case("r1", "u1").Default(qkeName); } else if (optor.getControls().size() == 1) { name = StringSwitch(qkeName) .Case("h", "ch") diff --git a/lib/Optimizer/Transforms/DecompositionPatterns.cpp b/lib/Optimizer/Transforms/DecompositionPatterns.cpp index 33791fb228..b776c8461c 100644 --- a/lib/Optimizer/Transforms/DecompositionPatterns.cpp +++ b/lib/Optimizer/Transforms/DecompositionPatterns.cpp @@ -623,34 +623,6 @@ struct SToR1 : public OpRewritePattern { } }; -// quake.s target -// ───────────────────────────────── -// (quake.z * quake.s) target -struct SAdjToSZ : public OpRewritePattern { - using OpRewritePattern::OpRewritePattern; - - void initialize() { setDebugName("SAdjToSZ"); } - - LogicalResult matchAndRewrite(quake::SOp op, - PatternRewriter &rewriter) const override { - if (!op.isAdj()) - return failure(); - - // Op info - auto loc = op->getLoc(); - auto parameters = op.getParameters(); - SmallVector controls(op.getControls()); - Value target = op.getTarget(); - - QuakeOperatorCreator qRewriter(rewriter); - qRewriter.create(loc, parameters, controls, target); - qRewriter.create(loc, parameters, controls, target); - qRewriter.selectWiresAndReplaceUses(op, controls, target); - rewriter.eraseOp(op); - return success(); - } -}; - //===----------------------------------------------------------------------===// // TOp decompositions //===----------------------------------------------------------------------===// @@ -1585,7 +1557,6 @@ void cudaq::populateWithAllDecompositionPatterns(RewritePatternSet &patterns) { // SOp patterns SToPhasedRx, SToR1, - SAdjToSZ, // TOp patterns TToPhasedRx, TToR1, diff --git a/python/cudaq/kernel/ast_bridge.py b/python/cudaq/kernel/ast_bridge.py index 8803ccf011..cae278143f 100644 --- a/python/cudaq/kernel/ast_bridge.py +++ b/python/cudaq/kernel/ast_bridge.py @@ -4032,5 +4032,4 @@ def compile_to_mlir(astModule, metadata, if len(bridge.dependentCaptureVars): extraMetaData['dependent_captures'] = bridge.dependentCaptureVars - bridge.module.dump() return bridge.module, bridge.argTypes, extraMetaData diff --git a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp index 4deefa3afb..f73f7c523e 100644 --- a/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp +++ b/python/runtime/cudaq/platform/py_alt_launch_kernel.cpp @@ -642,12 +642,12 @@ std::string getASM(const std::string &name, MlirModule module, PassManager pm(context); pm.addPass(cudaq::opt::createLambdaLiftingPass()); // Run most of the passes from hardware pipelines. - - pm.addPass(createCanonicalizerPass()); - pm.addPass(createCSEPass()); + pm.addNestedPass(createCanonicalizerPass()); + pm.addNestedPass(createCSEPass()); pm.addNestedPass(cudaq::opt::createClassicalMemToReg()); + pm.addPass(cudaq::opt::createLoopNormalize()); pm.addPass(cudaq::opt::createLoopUnroll()); - pm.addPass(createCanonicalizerPass()); + pm.addNestedPass(createCanonicalizerPass()); pm.addNestedPass(cudaq::opt::createLiftArrayAlloc()); pm.addPass(cudaq::opt::createGlobalizeArrayValues()); pm.addPass(cudaq::opt::createStatePreparation()); @@ -656,8 +656,8 @@ std::string getASM(const std::string &name, MlirModule module, pm.addPass(cudaq::opt::createApplyOpSpecializationPass()); cudaq::opt::addAggressiveEarlyInlining(pm); pm.addPass(createSymbolDCEPass()); - pm.addPass(createCanonicalizerPass()); - pm.addPass(createCSEPass()); + pm.addNestedPass(createCanonicalizerPass()); + pm.addNestedPass(createCSEPass()); pm.addNestedPass( cudaq::opt::createMultiControlDecompositionPass()); pm.addPass(cudaq::opt::createDecompositionPass( @@ -665,7 +665,7 @@ std::string getASM(const std::string &name, MlirModule module, "CHToCX", "CCZToCX", "CRzToCX", "CRyToCX", "CRxToCX", "CR1ToCX", "CCZToCX", "RxAdjToRx", "RyAdjToRy", "RzAdjToRz"}})); - pm.addPass(createCanonicalizerPass()); + pm.addNestedPass(createCanonicalizerPass()); pm.addNestedPass(cudaq::opt::createExpandControlVeqs()); pm.addNestedPass(cudaq::opt::createCombineQuantumAllocations()); cudaq::opt::addPipelineTranslateToOpenQASM(pm); diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index b0b6cbc356..2f5b19e714 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -289,6 +289,7 @@ def kernel(qubit_count: int): assert "0000" in counts assert "1111" in counts + def test_kernel_subveqs(): @cudaq.kernel @@ -303,6 +304,7 @@ def kernel(): assert len(counts) == 1 assert "11" in counts + def test_kernel_two_subveqs(): @cudaq.kernel @@ -318,6 +320,7 @@ def kernel(): assert len(counts) == 1 assert "011" in counts + def test_kernel_qubit_subveq(): @cudaq.kernel @@ -333,7 +336,7 @@ def kernel(): assert len(counts) == 1 assert "011" in counts - + def test_multiple_measurement(): @cudaq.kernel @@ -348,6 +351,7 @@ def kernel(): assert "00" in counts assert "10" in counts + def test_multiple_measurement_non_consecutive(): @cudaq.kernel diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp index 159ae0bcd6..57bdb3eac4 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp @@ -20,8 +20,6 @@ #include -#include - namespace { void tryCreateBucket(Aws::S3Crt::S3CrtClient &client, std::string const ®ion, std::string const &bucketName) { @@ -261,16 +259,12 @@ BraketExecutor::execute(std::vector &codesToExecute) { auto c = serverHelper->processResults(resultsJson, taskArn); for (auto ®Name : c.register_names()) { - std::cout << "Register name: " << regName << std::endl; results.emplace_back(c.to_map(regName), regName); - std::cout << "Sequential data: " << regName << std::endl; - for (auto d : c.sequential_data(regName)) { - std::cout << d << std::endl; - } results.back().sequentialData = c.sequential_data(regName); } i++; } + return sample_result(results); }, std::move(createOutcomes)); diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml index 66e485df1a..9d87058051 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml +++ b/runtime/cudaq/platform/default/rest/helpers/braket/braket.yml @@ -20,8 +20,6 @@ config: platform-lowering-config: "func.func(const-prop-complex,canonicalize,cse,lift-array-alloc),globalize-array-values,state-prep,unitary-synthesis,canonicalize,apply-op-specialization,aggressive-early-inlining,unrolling-pipeline,func.func(lower-to-cfg),canonicalize,func.func(multicontrol-decomposition),decomposition{enable-patterns=SToR1,TToR1,R1ToU3,U3ToRotations,CHToCX,CCZToCX,CRzToCX,CRyToCX,CRxToCX,CR1ToCX,RxAdjToRx,RyAdjToRy,RzAdjToRz},func.func(expand-control-veqs,combine-quantum-alloc,canonicalize,combine-measurements)" # Tell the rest-qpu that we are generating OpenQASM 2.0. codegen-emission: qasm2 - # Additional passes to run after lowering to QUAKE - #post-codegen-passes: "remove-measurements" # Library mode is only for simulators, physical backends must turn this off library-mode: false From 21888f4df59a223d2e713060d83705cfe678220c Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 15:18:01 -0800 Subject: [PATCH 41/47] Fix test failures and address CR comments Signed-off-by: Anna Gringauze --- lib/Optimizer/CodeGen/Pipelines.cpp | 5 +++-- runtime/common/BaseRemoteRESTQPU.h | 14 ++++++++++++++ .../rest/helpers/braket/BraketServerHelper.cpp | 16 ++++++++-------- targettests/execution/graph_coloring-1.cpp | 2 +- targettests/execution/graph_coloring.cpp | 2 +- test/Quake/combine_measurements.qke | 5 ++--- 6 files changed, 29 insertions(+), 15 deletions(-) diff --git a/lib/Optimizer/CodeGen/Pipelines.cpp b/lib/Optimizer/CodeGen/Pipelines.cpp index 95f8debb76..a5cfe22961 100644 --- a/lib/Optimizer/CodeGen/Pipelines.cpp +++ b/lib/Optimizer/CodeGen/Pipelines.cpp @@ -42,9 +42,10 @@ void cudaq::opt::commonPipelineConvertToQIR( } void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) { - pm.addPass(createCanonicalizerPass()); - pm.addPass(createCSEPass()); + pm.addNestedPass(createCanonicalizerPass()); + pm.addNestedPass(createCSEPass()); pm.addNestedPass(createClassicalMemToReg()); + pm.addNestedPass(createCanonicalizerPass()); pm.addPass(createSymbolDCEPass()); } diff --git a/runtime/common/BaseRemoteRESTQPU.h b/runtime/common/BaseRemoteRESTQPU.h index fba54a2da7..9ae62fe21a 100644 --- a/runtime/common/BaseRemoteRESTQPU.h +++ b/runtime/common/BaseRemoteRESTQPU.h @@ -470,6 +470,17 @@ class BaseRemoteRESTQPU : public cudaq::QPU { throw std::runtime_error("Could not successfully apply quake-synth."); } + // Delay combining measurements for backends that cannot handle + // subveqs and multiple measurements until we created the emulation code. + auto combineMeasurements = + passPipelineConfig.find("combine-measurements") != std::string::npos; + if (emulate && combineMeasurements) { + std::regex combine("(.*)([,]*)([ ]*)combine-measurements(.*)"); + std::string replacement("$1$4"); + passPipelineConfig = + std::regex_replace(passPipelineConfig, combine, replacement); + } + runPassPipeline(passPipelineConfig, moduleOp); auto entryPointFunc = moduleOp.lookupSymbol( @@ -548,6 +559,9 @@ class BaseRemoteRESTQPU : public cudaq::QPU { } } + if (emulate && combineMeasurements) + runPassPipeline("func.func(combine-measurements)", moduleOp); + // Get the code gen translation auto translation = cudaq::getTranslation(codegenTranslation); diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp index f5cfb96a4a..2af49b5410 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp @@ -66,13 +66,13 @@ void BraketServerHelper::initialize(BackendConfig config) { if (!config["shots"].empty()) this->setShots(std::stoul(config["shots"])); - const auto emulate_it = config.find("emulate"); - if (emulate_it != config.end() && emulate_it->second == "true") { - cudaq::info("Emulation is enabled, ignore all Amazon Braket connection " - "specific information."); - backendConfig = std::move(config); - return; - } + // const auto emulate_it = config.find("emulate"); + // if (emulate_it != config.end() && emulate_it->second == "true") { + // cudaq::info("Emulation is enabled, ignore all Amazon Braket connection " + // "specific information."); + // backendConfig = std::move(config); + // return; + // } parseConfigForCommonParams(config); @@ -172,7 +172,7 @@ sample_result BraketServerHelper::processResults(ServerMessage &resultsJson, // Get a reduced list of qubit numbers that were in the original program // so that we can slice the output data and extract the bits that the user - // was interested in. Sort by QIR qubit number. + // was interested in. Sort by OpenQasm2 qubit number. std::vector qubitNumbers; qubitNumbers.reserve(output_names.size()); for (auto &[result, info] : output_names) { diff --git a/targettests/execution/graph_coloring-1.cpp b/targettests/execution/graph_coloring-1.cpp index 88b5fae654..c669d054a4 100644 --- a/targettests/execution/graph_coloring-1.cpp +++ b/targettests/execution/graph_coloring-1.cpp @@ -8,7 +8,7 @@ // REQUIRES: c++20 // clang-format off -// RUN: nvq++ %s -o %t --target braket --emulate && %t FileCheck %s +// RUN: nvq++ %s -o %t --target braket --emulate && %t | FileCheck %s // RUN: nvq++ %s -o %t --target quantinuum --emulate && %t | FileCheck %s // clang-format on diff --git a/targettests/execution/graph_coloring.cpp b/targettests/execution/graph_coloring.cpp index 93147e4a72..262743ad99 100644 --- a/targettests/execution/graph_coloring.cpp +++ b/targettests/execution/graph_coloring.cpp @@ -8,7 +8,7 @@ // REQUIRES: c++20 // clang-format off -// RUN: nvq++ %s -o %t --target braket --emulate && %t FileCheck %s +// RUN: nvq++ %s -o %t --target braket --emulate && %t | FileCheck %s // RUN: nvq++ %s -o %t --target quantinuum --emulate && %t | FileCheck %s // clang-format on diff --git a/test/Quake/combine_measurements.qke b/test/Quake/combine_measurements.qke index 24bc00e3f4..3dd80e67b6 100644 --- a/test/Quake/combine_measurements.qke +++ b/test/Quake/combine_measurements.qke @@ -9,7 +9,6 @@ // RUN: cudaq-opt -combine-measurements -canonicalize %s | FileCheck %s module { - func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint"} { %0 = quake.alloca !quake.veq<2> %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref @@ -44,9 +43,9 @@ module { func.func @mz_2bits_extract_non_consecutive() attributes {"cudaq-entrypoint"} { %0 = quake.alloca !quake.veq<3> - %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref + %1 = quake.extract_ref %0[0] : (!quake.veq<3>) -> !quake.ref %measOut = quake.mz %1 : (!quake.ref) -> !quake.measure - %2 = quake.extract_ref %0[2] : (!quake.veq<2>) -> !quake.ref + %2 = quake.extract_ref %0[2] : (!quake.veq<3>) -> !quake.ref %measOut_0 = quake.mz %2 : (!quake.ref) -> !quake.measure return } From 295b760525ddecda632aa35924146a1151a7d44d Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 15:39:54 -0800 Subject: [PATCH 42/47] Fix test failures Signed-off-by: Anna Gringauze --- program.py | 120 +++++++++++++++++++++++++++ python/tests/backends/test_braket.py | 14 ++-- runtime/common/BaseRemoteRESTQPU.h | 4 +- 3 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 program.py diff --git a/program.py b/program.py new file mode 100644 index 0000000000..494aef2f0e --- /dev/null +++ b/program.py @@ -0,0 +1,120 @@ +# ============================================================================ # +# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. # +# All rights reserved. # +# # +# This source code and the accompanying materials are made available under # +# the terms of the Apache License 2.0 which accompanies this distribution. # +# ============================================================================ # + +import cudaq + +device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" +cudaq.set_target("braket", emulate=True, machine=device_arn) + +def test_kernel_subveqs(): + + @cudaq.kernel + def kernel(): + qreg = cudaq.qvector(4) + x(qreg[1]) + x(qreg[2]) + v = qreg[1:3] + mz(v) + + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 1 + assert "11" in counts + +test_kernel_subveqs() + +def test_kernel_two_subveqs(): + + @cudaq.kernel + def kernel(): + qreg = cudaq.qvector(4) + x(qreg[1]) + x(qreg[2]) + v1 = qreg[0:2] + mz(v1) + v2 = qreg[2:3] + mz(v2) + + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 1 + assert "011" in counts + + +def test_kernel_qubit_subveq(): + + @cudaq.kernel + def kernel(): + qreg = cudaq.qvector(4) + x(qreg[1]) + x(qreg[2]) + v1 = qreg[0:2] + mz(v1) + v2 = qreg[2] + mz(v2) + + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 1 + assert "011" in counts + + +def test_multiple_measurement(): + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(2) + h(qubits[0]) + mz(qubits[0]) + mz(qubits[1]) + + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 2 + assert "00" in counts + assert "10" in counts + + +def test_multiple_measurement_non_consecutive(): + + @cudaq.kernel + def kernel(): + qubits = cudaq.qvector(3) + x(qubits[0]) + x(qubits[2]) + mz(qubits[0]) + mz(qubits[2]) + + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 1 + assert "11" in counts + + +def test_qvector_slicing(): + + @cudaq.kernel + def kernel(): + q = cudaq.qvector(4) + x(q.front(2)) + mz(q) + + counts = cudaq.sample(kernel, shots_count=100) + assert len(counts) == 1 + assert "1100" in counts + + +def test_mid_circuit_measurement(): + + @cudaq.kernel + def simple(): + q = cudaq.qvector(2) + h(q[0]) + if mz(q[0]): + x(q[1]) + mz(q) + + ## error: 'cf.cond_br' op unable to translate op to OpenQASM 2.0 + with pytest.raises(RuntimeError) as e: + cudaq.sample(simple, shots_count=100).dump() + assert "Could not successfully translate to qasm2" in repr(e) \ No newline at end of file diff --git a/python/tests/backends/test_braket.py b/python/tests/backends/test_braket.py index 2f5b19e714..79cca789ce 100644 --- a/python/tests/backends/test_braket.py +++ b/python/tests/backends/test_braket.py @@ -312,9 +312,10 @@ def kernel(): qreg = cudaq.qvector(4) x(qreg[1]) x(qreg[2]) - v = qreg[0:2] - v = qreg[2:3] - mz(v) + v1 = qreg[0:2] + mz(v1) + v2 = qreg[2:3] + mz(v2) counts = cudaq.sample(kernel, shots_count=100) assert len(counts) == 1 @@ -328,9 +329,10 @@ def kernel(): qreg = cudaq.qvector(4) x(qreg[1]) x(qreg[2]) - v = qreg[0:2] - v = qreg[2] - mz(v) + v1 = qreg[0:2] + mz(v1) + v2 = qreg[2] + mz(v2) counts = cudaq.sample(kernel, shots_count=100) assert len(counts) == 1 diff --git a/runtime/common/BaseRemoteRESTQPU.h b/runtime/common/BaseRemoteRESTQPU.h index 9ae62fe21a..3471988fcd 100644 --- a/runtime/common/BaseRemoteRESTQPU.h +++ b/runtime/common/BaseRemoteRESTQPU.h @@ -475,8 +475,8 @@ class BaseRemoteRESTQPU : public cudaq::QPU { auto combineMeasurements = passPipelineConfig.find("combine-measurements") != std::string::npos; if (emulate && combineMeasurements) { - std::regex combine("(.*)([,]*)([ ]*)combine-measurements(.*)"); - std::string replacement("$1$4"); + std::regex combine("(.*),([ ]*)combine-measurements(.*)"); + std::string replacement("$1$3"); passPipelineConfig = std::regex_replace(passPipelineConfig, combine, replacement); } From f22fc33bda8bca01876826aaf5d5c607366d0af7 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 17:00:41 -0800 Subject: [PATCH 43/47] Update combine-measurements after merging with main Signed-off-by: Anna Gringauze --- .../Transforms/CombineMeasurements.cpp | 34 +++-- program.py | 120 ------------------ test/Quake/combine_measurements.qke | 32 +++-- 3 files changed, 45 insertions(+), 141 deletions(-) delete mode 100644 program.py diff --git a/lib/Optimizer/Transforms/CombineMeasurements.cpp b/lib/Optimizer/Transforms/CombineMeasurements.cpp index 1dd768425c..27e47bba2c 100644 --- a/lib/Optimizer/Transforms/CombineMeasurements.cpp +++ b/lib/Optimizer/Transforms/CombineMeasurements.cpp @@ -7,6 +7,7 @@ ******************************************************************************/ #include "PassDetails.h" +#include "cudaq/Optimizer/Builder/Factory.h" #include "cudaq/Optimizer/CodeGen/QIRAttributeNames.h" #include "cudaq/Optimizer/Dialect/CC/CCOps.h" #include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h" @@ -127,7 +128,7 @@ class ExtendQubitMeasurePattern : public OpRewritePattern { else return extract.emitError("Non-constant index in ExtractRef"); - auto offset = idx + analysis.measurements[measure.getMeasOut()]; + auto offset = analysis.measurements[measure.getMeasOut()]; analysis.resultQubitVals[offset] = std::make_pair(idx, std::to_string(idx)); @@ -169,27 +170,34 @@ class ExtendVeqMeasurePattern : public OpRewritePattern { // And collect output names information: `"[[[0,[1,"q0"]],[1,[2,"q1"]]]]"` LogicalResult matchAndRewrite(quake::MzOp measure, PatternRewriter &rewriter) const override { - auto veqOp = measure.getOperand(0); if (auto subveq = veqOp.getDefiningOp()) { - Value lowOp = subveq.getLow(); - Value highOp = subveq.getHigh(); - - auto constLow = lowOp.getDefiningOp(); - if (!constLow) - return subveq.emitError("Non-constant low index in subveq"); - auto constHigh = highOp.getDefiningOp(); - if (!constHigh) - return subveq.emitError("Non-constant high index in subveq"); + std::size_t low; + if (subveq.hasConstantLowerBound()) + low = subveq.getConstantLowerBound(); + else { + auto value = cudaq::opt::factory::getIntIfConstant(subveq.getLower()); + if (!value.has_value()) + return subveq.emitError("Non-constant lower index in subveq"); + low = static_cast(value.value()); + } - auto low = static_cast(constLow.value()); - auto high = static_cast(constHigh.value()); + std::size_t high; + if (subveq.hasConstantUpperBound()) + high = subveq.getConstantUpperBound(); + else { + auto value = cudaq::opt::factory::getIntIfConstant(subveq.getUpper()); + if (!value.has_value()) + return subveq.emitError("Non-constant upper index in subveq"); + high = static_cast(value.value()); + } for (std::size_t i = low; i <= high; i++) { auto start = analysis.measurements[measure.getMeasOut()]; auto offset = i - low + start; analysis.resultQubitVals[offset] = std::make_pair(i, std::to_string(i)); } + if (measure == analysis.lastMeasurement) rewriter.replaceOpWithNewOp( measure, measure.getResultTypes(), ValueRange{subveq.getVeq()}, diff --git a/program.py b/program.py deleted file mode 100644 index 494aef2f0e..0000000000 --- a/program.py +++ /dev/null @@ -1,120 +0,0 @@ -# ============================================================================ # -# Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. # -# All rights reserved. # -# # -# This source code and the accompanying materials are made available under # -# the terms of the Apache License 2.0 which accompanies this distribution. # -# ============================================================================ # - -import cudaq - -device_arn = "arn:aws:braket:::device/quantum-simulator/amazon/sv1" -cudaq.set_target("braket", emulate=True, machine=device_arn) - -def test_kernel_subveqs(): - - @cudaq.kernel - def kernel(): - qreg = cudaq.qvector(4) - x(qreg[1]) - x(qreg[2]) - v = qreg[1:3] - mz(v) - - counts = cudaq.sample(kernel, shots_count=100) - assert len(counts) == 1 - assert "11" in counts - -test_kernel_subveqs() - -def test_kernel_two_subveqs(): - - @cudaq.kernel - def kernel(): - qreg = cudaq.qvector(4) - x(qreg[1]) - x(qreg[2]) - v1 = qreg[0:2] - mz(v1) - v2 = qreg[2:3] - mz(v2) - - counts = cudaq.sample(kernel, shots_count=100) - assert len(counts) == 1 - assert "011" in counts - - -def test_kernel_qubit_subveq(): - - @cudaq.kernel - def kernel(): - qreg = cudaq.qvector(4) - x(qreg[1]) - x(qreg[2]) - v1 = qreg[0:2] - mz(v1) - v2 = qreg[2] - mz(v2) - - counts = cudaq.sample(kernel, shots_count=100) - assert len(counts) == 1 - assert "011" in counts - - -def test_multiple_measurement(): - - @cudaq.kernel - def kernel(): - qubits = cudaq.qvector(2) - h(qubits[0]) - mz(qubits[0]) - mz(qubits[1]) - - counts = cudaq.sample(kernel, shots_count=100) - assert len(counts) == 2 - assert "00" in counts - assert "10" in counts - - -def test_multiple_measurement_non_consecutive(): - - @cudaq.kernel - def kernel(): - qubits = cudaq.qvector(3) - x(qubits[0]) - x(qubits[2]) - mz(qubits[0]) - mz(qubits[2]) - - counts = cudaq.sample(kernel, shots_count=100) - assert len(counts) == 1 - assert "11" in counts - - -def test_qvector_slicing(): - - @cudaq.kernel - def kernel(): - q = cudaq.qvector(4) - x(q.front(2)) - mz(q) - - counts = cudaq.sample(kernel, shots_count=100) - assert len(counts) == 1 - assert "1100" in counts - - -def test_mid_circuit_measurement(): - - @cudaq.kernel - def simple(): - q = cudaq.qvector(2) - h(q[0]) - if mz(q[0]): - x(q[1]) - mz(q) - - ## error: 'cf.cond_br' op unable to translate op to OpenQASM 2.0 - with pytest.raises(RuntimeError) as e: - cudaq.sample(simple, shots_count=100).dump() - assert "Could not successfully translate to qasm2" in repr(e) \ No newline at end of file diff --git a/test/Quake/combine_measurements.qke b/test/Quake/combine_measurements.qke index 3dd80e67b6..d4195c1904 100644 --- a/test/Quake/combine_measurements.qke +++ b/test/Quake/combine_measurements.qke @@ -9,7 +9,7 @@ // RUN: cudaq-opt -combine-measurements -canonicalize %s | FileCheck %s module { - func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint"} { +func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint"} { %0 = quake.alloca !quake.veq<2> %1 = quake.extract_ref %0[0] : (!quake.veq<2>) -> !quake.ref %measOut = quake.mz %1 : (!quake.ref) -> !quake.measure @@ -18,7 +18,7 @@ module { return } -// CHECK: func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[2,\[1,\\221\\22\]\]\]\]}}"} { +// CHECK-LABEL: func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[1,\[1,\\221\\22\]\]\]\]}}"} { // CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<2> // CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<2>) -> !cc.stdvec // CHECK: return @@ -34,8 +34,7 @@ module { %measOut_0 = quake.mz %2 : (!quake.ref) -> !quake.measure return } - -// CHECK: func.func @mz_2bits_extract_cst_op_index() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[2,\[1,\\221\\22\]\]\]\]}}"} { +// CHECK-LABEL: func.func @mz_2bits_extract_cst_op_index() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[1,\[1,\\221\\22\]\]\]\]}}"} { // CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<2> // CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<2>) -> !cc.stdvec // CHECK: return @@ -50,7 +49,7 @@ module { return } -// CHECK: func.func @mz_2bits_extract_cst_index() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[2,\[1,\\222\\22\]\]\]\]}}"} { +// CHECK-LABEL: func.func @mz_2bits_extract_non_consecutive() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[1,\[2,\\222\\22\]\]\]\]}}"} { // CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<3> // CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<3>) -> !cc.stdvec // CHECK: return @@ -64,7 +63,7 @@ module { return } -// CHECK: func.func @subveq_4_1() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\]\]\]}}"} { +// CHECK-LABEL: func.func @subveq_4_1() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\]\]\]}}"} { // CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> // CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec // CHECK: return @@ -79,7 +78,7 @@ module { return } -// CHECK: func.func @subveq_4_2() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\],\[1,\[2,\\222\\22\]\]\]\]}}"} { +// CHECK-LABEL: func.func @subveq_4_2() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[1,\\221\\22\]\],\[1,\[2,\\222\\22\]\]\]\]}}"} { // CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> // CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec // CHECK: return @@ -94,7 +93,24 @@ module { return } -// CHECK: func.func @subveq_4_4() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[1,\[1,\\221\\22\]\],\[2,\[2,\\222\\22\]\],\[3,\[3,\\223\\22\]\]\]\]}}"} { +// CHECK-LABEL: func.func @subveq_4_4() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[1,\[1,\\221\\22\]\],\[2,\[2,\\222\\22\]\],\[3,\[3,\\223\\22\]\]\]\]}}"} { +// CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> +// CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec +// CHECK: return +// CHECK: } + + func.func @mz_2subveqs_extract() attributes {"cudaq-entrypoint"} { + %0 = quake.alloca !quake.veq<4> + %1 = quake.extract_ref %0[1] : (!quake.veq<4>) -> !quake.ref + %2 = quake.extract_ref %0[2] : (!quake.veq<4>) -> !quake.ref + %3 = quake.subveq %0, 0, 1 : (!quake.veq<4>) -> !quake.veq<2> + %measOut = quake.mz %3 : (!quake.veq<2>) -> !cc.stdvec + %4 = quake.subveq %0, 2, 2 : (!quake.veq<4>) -> !quake.veq<1> + %measOut_0 = quake.mz %4 : (!quake.veq<1>) -> !cc.stdvec + return + } + +// CHECK-LABEL: func.func @mz_2subveqs_extract() attributes {"cudaq-entrypoint", output_names = "{{\[\[\[0,\[0,\\220\\22\]\],\[1,\[1,\\221\\22\]\],\[2,\[2,\\222\\22\]\]\]\]}}"} { // CHECK: %[[VAL_0:.*]] = quake.alloca !quake.veq<4> // CHECK: %[[VAL_1:.*]] = quake.mz %[[VAL_0]] : (!quake.veq<4>) -> !cc.stdvec // CHECK: return From b7c6ef53daaecf93f590630b553995ca36be4224 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 17:19:02 -0800 Subject: [PATCH 44/47] Address CR comments Signed-off-by: Anna Gringauze --- .../rest/helpers/braket/BraketServerHelper.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp index 2af49b5410..01a4bdfd8a 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp @@ -66,13 +66,13 @@ void BraketServerHelper::initialize(BackendConfig config) { if (!config["shots"].empty()) this->setShots(std::stoul(config["shots"])); - // const auto emulate_it = config.find("emulate"); - // if (emulate_it != config.end() && emulate_it->second == "true") { - // cudaq::info("Emulation is enabled, ignore all Amazon Braket connection " - // "specific information."); - // backendConfig = std::move(config); - // return; - // } + const auto emulate_it = config.find("emulate"); + if (emulate_it != config.end() && emulate_it->second == "true") { + cudaq::info("Emulation is enabled, ignore all Amazon Braket connection " + "specific information."); + backendConfig = std::move(config); + return; + } parseConfigForCommonParams(config); From ae14c377dbdfcc452ac8ba26fdd3b85b68bfc6db Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 17:22:08 -0800 Subject: [PATCH 45/47] Format Signed-off-by: Anna Gringauze --- .../rest/helpers/braket/BraketServerHelper.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp index 01a4bdfd8a..c980914bea 100644 --- a/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp +++ b/runtime/cudaq/platform/default/rest/helpers/braket/BraketServerHelper.cpp @@ -67,12 +67,12 @@ void BraketServerHelper::initialize(BackendConfig config) { this->setShots(std::stoul(config["shots"])); const auto emulate_it = config.find("emulate"); - if (emulate_it != config.end() && emulate_it->second == "true") { - cudaq::info("Emulation is enabled, ignore all Amazon Braket connection " - "specific information."); - backendConfig = std::move(config); - return; - } + if (emulate_it != config.end() && emulate_it->second == "true") { + cudaq::info("Emulation is enabled, ignore all Amazon Braket connection " + "specific information."); + backendConfig = std::move(config); + return; + } parseConfigForCommonParams(config); From 3966ee3fa0b4b4bc4cf57d1c64cebf97f750ea37 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 17:30:08 -0800 Subject: [PATCH 46/47] Address CR comments --- runtime/common/BaseRemoteRESTQPU.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/common/BaseRemoteRESTQPU.h b/runtime/common/BaseRemoteRESTQPU.h index 3471988fcd..8ce53e6798 100644 --- a/runtime/common/BaseRemoteRESTQPU.h +++ b/runtime/common/BaseRemoteRESTQPU.h @@ -479,6 +479,9 @@ class BaseRemoteRESTQPU : public cudaq::QPU { std::string replacement("$1$3"); passPipelineConfig = std::regex_replace(passPipelineConfig, combine, replacement); + cudaq::info("Delaying combine-measurements due to emulation. " + "Updating pipeline to {}", + passPipelineConfig); } runPassPipeline(passPipelineConfig, moduleOp); From 797ea895d6a802488dfd265ec572040227c936e8 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 26 Nov 2024 17:31:48 -0800 Subject: [PATCH 47/47] DCO Remediation Commit for Anna Gringauze I, Anna Gringauze , hereby add my Signed-off-by to this commit: 3966ee3fa0b4b4bc4cf57d1c64cebf97f750ea37 Signed-off-by: Anna Gringauze --- runtime/common/BaseRemoteRESTQPU.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/common/BaseRemoteRESTQPU.h b/runtime/common/BaseRemoteRESTQPU.h index 8ce53e6798..536773f839 100644 --- a/runtime/common/BaseRemoteRESTQPU.h +++ b/runtime/common/BaseRemoteRESTQPU.h @@ -479,7 +479,7 @@ class BaseRemoteRESTQPU : public cudaq::QPU { std::string replacement("$1$3"); passPipelineConfig = std::regex_replace(passPipelineConfig, combine, replacement); - cudaq::info("Delaying combine-measurements due to emulation. " + cudaq::info("Delaying combine-measurements pass due to emulation. " "Updating pipeline to {}", passPipelineConfig); }