From ac23d69cea4b66781391b69a1c8777aeea10c17b Mon Sep 17 00:00:00 2001 From: Erick Ochoa Lopez Date: Wed, 16 Apr 2025 16:14:24 +0000 Subject: [PATCH 01/49] Update LLVM and MLIR-HLO --- .dep-versions | 5 +++-- mlir/llvm-project | 2 +- mlir/mlir-hlo | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.dep-versions b/.dep-versions index b224a7f56f..2e17e57aaf 100644 --- a/.dep-versions +++ b/.dep-versions @@ -1,7 +1,7 @@ # Always update the version check in catalyst.__init__ when changing the JAX version. jax=0.4.28 -mhlo=89a891c986650c33df76885f5620e0a92150d90f -llvm=3a8316216807d64a586b971f51695e23883331f7 +mhlo=39c37c43fb9db18144f2e155a0fe65864646a968 +llvm=6f2c61071c274a1b5e212e6ad4114641ec7c7fc3 enzyme=v0.0.149 # Always remove custom PL/LQ versions before release. @@ -13,3 +13,4 @@ pennylane=0.41.0-dev56 # For a custom LQ/LK version, update the package version here and at # 'doc/requirements.txt' lightning=0.41.0-dev22 + diff --git a/mlir/llvm-project b/mlir/llvm-project index 3a83162168..6f2c61071c 160000 --- a/mlir/llvm-project +++ b/mlir/llvm-project @@ -1 +1 @@ -Subproject commit 3a8316216807d64a586b971f51695e23883331f7 +Subproject commit 6f2c61071c274a1b5e212e6ad4114641ec7c7fc3 diff --git a/mlir/mlir-hlo b/mlir/mlir-hlo index 89a891c986..39c37c43fb 160000 --- a/mlir/mlir-hlo +++ b/mlir/mlir-hlo @@ -1 +1 @@ -Subproject commit 89a891c986650c33df76885f5620e0a92150d90f +Subproject commit 39c37c43fb9db18144f2e155a0fe65864646a968 From 16bc3578e366645c4d3a04150e2b2399c49939cc Mon Sep 17 00:00:00 2001 From: Erick Ochoa Lopez Date: Wed, 16 Apr 2025 16:21:58 +0000 Subject: [PATCH 02/49] Update TopologicalSortUtils.h's location. Moved to Analysis on May 22, 2024. See https://github.com/llvm/llvm-project/pull/92563 and https://github.com/llvm/llvm-project/commit/b00e0c167186d69e1e6bceda57c09b272bd6acfc --- mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp | 2 +- mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp b/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp index 6790c920e6..187a9bac4d 100644 --- a/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp +++ b/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp @@ -17,7 +17,7 @@ #include "llvm/Support/Debug.h" #include "mlir/Analysis/SliceAnalysis.h" -#include "mlir/Transforms/TopologicalSortUtils.h" +#include "mlir/Analysis/TopologicalSortUtils.h" #include "QEC/IR/QECDialect.h" #include "QEC/IR/QECOpInterfaces.h" diff --git a/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp b/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp index af49ffe81e..4d37ae810e 100644 --- a/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp +++ b/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp @@ -16,7 +16,7 @@ #include "llvm/Support/Debug.h" -#include "mlir/Transforms/TopologicalSortUtils.h" +#include "mlir/Analysis/TopologicalSortUtils.h" #include "QEC/IR/QECDialect.h" #include "QEC/IR/QECOpInterfaces.h" From d81e8d2a65f9d97ae7ce10b7c23fb3d35d9c3950 Mon Sep 17 00:00:00 2001 From: Tzung-Han Juang Date: Fri, 16 Aug 2024 12:06:54 -0400 Subject: [PATCH 03/49] Use operator==(StringRef, StringRef) StringRef::equals has been marked deprecated https://github.com/llvm/llvm-project/pull/92351 https://github.com/llvm/llvm-project/commit/de483ad513895c0adf7f21c7001c30f031998ea3 --- mlir/lib/Catalyst/Transforms/AsyncUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/lib/Catalyst/Transforms/AsyncUtils.cpp b/mlir/lib/Catalyst/Transforms/AsyncUtils.cpp index a0c27129cb..a295156330 100644 --- a/mlir/lib/Catalyst/Transforms/AsyncUtils.cpp +++ b/mlir/lib/Catalyst/Transforms/AsyncUtils.cpp @@ -215,7 +215,7 @@ std::optional AsyncUtils::getCalleeSafe(LLVM::CallOp callOp) bool AsyncUtils::isFunctionNamed(LLVM::LLVMFuncOp funcOp, llvm::StringRef expectedName) { llvm::StringRef observedName = funcOp.getSymName(); - return observedName.equals(expectedName); + return observedName == expectedName; } bool AsyncUtils::isMlirAsyncRuntimeCreateValue(LLVM::LLVMFuncOp funcOp) From 3b70b9fe2617df4899a7de9f3de58e79d3b70014 Mon Sep 17 00:00:00 2001 From: Erick Ochoa Lopez Date: Wed, 16 Apr 2025 16:35:30 +0000 Subject: [PATCH 04/49] Comment out deprecated bufferization pipelines --- mlir/lib/Driver/Pipelines.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mlir/lib/Driver/Pipelines.cpp b/mlir/lib/Driver/Pipelines.cpp index d1e2dc3eb9..af0ad8f08d 100644 --- a/mlir/lib/Driver/Pipelines.cpp +++ b/mlir/lib/Driver/Pipelines.cpp @@ -72,13 +72,13 @@ void createBufferizationPipeline(OpPassManager &pm) pm.addPass(mlir::createSCFBufferizePass()); pm.addPass(mlir::createConvertTensorToLinalgPass()); pm.addPass(mlir::createConvertElementwiseToLinalgPass()); - pm.addPass(mlir::arith::createArithBufferizePass()); + //pm.addPass(mlir::arith::createArithBufferizePass()); pm.addPass(mlir::bufferization::createEmptyTensorToAllocTensorPass()); - pm.addNestedPass(mlir::bufferization::createBufferizationBufferizePass()); - pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); + //pm.addNestedPass(mlir::bufferization::createBufferizationBufferizePass()); + //pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); pm.addPass(catalyst::createCatalystBufferizationPass()); - pm.addNestedPass(mlir::createLinalgBufferizePass()); - pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); + //pm.addNestedPass(mlir::createLinalgBufferizePass()); + //pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); pm.addPass(catalyst::createQuantumBufferizationPass()); pm.addPass(mlir::func::createFuncBufferizePass()); pm.addNestedPass(mlir::bufferization::createFinalizingBufferizePass()); From c037c721851776e123d8375bd1a42fbf6c46c696 Mon Sep 17 00:00:00 2001 From: Tzung-Han Juang Date: Wed, 16 Apr 2025 16:41:06 +0000 Subject: [PATCH 05/49] Add disableVerification to translateModuleToLLVMIR See https://github.com/llvm/llvm-project/pull/94445 and https://github.com/llvm/llvm-project/commit/9b2a349991a87b2d9d576b0b1f63f357870449b1 --- mlir/lib/Driver/CompilerDriver.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Driver/CompilerDriver.cpp b/mlir/lib/Driver/CompilerDriver.cpp index ec4926fe46..20baeef95b 100644 --- a/mlir/lib/Driver/CompilerDriver.cpp +++ b/mlir/lib/Driver/CompilerDriver.cpp @@ -731,9 +731,11 @@ LogicalResult QuantumDriverMain(const CompilerOptions &options, CompilerOutput & if (runTranslate && (inType == InputType::MLIR)) { TimingScope translateTiming = timing.nest("Translate"); + // TODO: Change to true for release. + bool disableVerification = false; llvmModule = timer::timer(translateModuleToLLVMIR, "translateModuleToLLVMIR", - /* add_endl */ false, *mlirModule, llvmContext, "LLVMDialectModule"); + /* add_endl */ false, *mlirModule, llvmContext, "LLVMDialectModule", disableVerification); if (!llvmModule) { CO_MSG(options, Verbosity::Urgent, "Failed to translate LLVM module\n"); return failure(); From c30269c810febad6b8cc00e73a962ec58a8890c5 Mon Sep 17 00:00:00 2001 From: Tzung-Han Juang Date: Wed, 16 Apr 2025 16:48:35 +0000 Subject: [PATCH 06/49] Comment out retired bufferization passes See https://github.com/llvm/llvm-project/pull/93488 https://github.com/llvm/llvm-project/commit/2fc510643747dc70abdf8f2f7efcc7763d1392cb --- frontend/catalyst/pipelines.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/catalyst/pipelines.py b/frontend/catalyst/pipelines.py index acd2e6899c..e43f89dbea 100644 --- a/frontend/catalyst/pipelines.py +++ b/frontend/catalyst/pipelines.py @@ -227,13 +227,13 @@ def get_bufferization_stage(_options: CompileOptions) -> List[str]: "scf-bufferize", "convert-tensor-to-linalg", # tensor.pad "convert-elementwise-to-linalg", # Must be run before --arith-bufferize - "arith-bufferize", + #"arith-bufferize", "empty-tensor-to-alloc-tensor", - "func.func(bufferization-bufferize)", - "func.func(tensor-bufferize)", + #"func.func(bufferization-bufferize)", + #"func.func(tensor-bufferize)", "catalyst-bufferize", # Must be run before -- func.func(linalg-bufferize) - "func.func(linalg-bufferize)", - "func.func(tensor-bufferize)", + #"func.func(linalg-bufferize)", + #"func.func(tensor-bufferize)", "quantum-bufferize", "func-bufferize", "func.func(finalizing-bufferize)", From c40c02fd5784533e29ae015c900e4434c233239c Mon Sep 17 00:00:00 2001 From: Tzung-Han Juang Date: Tue, 20 Aug 2024 11:05:11 -0400 Subject: [PATCH 07/49] Temporarily disable finalizing-bufferization for debugging --- frontend/catalyst/pipelines.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/catalyst/pipelines.py b/frontend/catalyst/pipelines.py index e43f89dbea..886cef8320 100644 --- a/frontend/catalyst/pipelines.py +++ b/frontend/catalyst/pipelines.py @@ -236,7 +236,7 @@ def get_bufferization_stage(_options: CompileOptions) -> List[str]: #"func.func(tensor-bufferize)", "quantum-bufferize", "func-bufferize", - "func.func(finalizing-bufferize)", + #"func.func(finalizing-bufferize)", "canonicalize", # Remove dead memrefToTensorOp's "gradient-postprocess", # introduced during gradient-bufferize of callbacks From 10ec118ef6b84bf2e8dc7676f0a722fa141b03e6 Mon Sep 17 00:00:00 2001 From: Tzung-Han Juang Date: Tue, 20 Aug 2024 18:52:43 -0400 Subject: [PATCH 08/49] Remove all passes and use one-shot-bufferize only --- frontend/catalyst/pipelines.py | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/frontend/catalyst/pipelines.py b/frontend/catalyst/pipelines.py index 886cef8320..679da05018 100644 --- a/frontend/catalyst/pipelines.py +++ b/frontend/catalyst/pipelines.py @@ -220,35 +220,7 @@ def get_quantum_compilation_stage(options: CompileOptions) -> List[str]: def get_bufferization_stage(_options: CompileOptions) -> List[str]: """Returns the list of passes that performs bufferization""" bufferization = [ - "one-shot-bufferize{dialect-filter=memref}", - "inline", - "gradient-preprocess", - "gradient-bufferize", - "scf-bufferize", - "convert-tensor-to-linalg", # tensor.pad - "convert-elementwise-to-linalg", # Must be run before --arith-bufferize - #"arith-bufferize", - "empty-tensor-to-alloc-tensor", - #"func.func(bufferization-bufferize)", - #"func.func(tensor-bufferize)", - "catalyst-bufferize", # Must be run before -- func.func(linalg-bufferize) - #"func.func(linalg-bufferize)", - #"func.func(tensor-bufferize)", - "quantum-bufferize", - "func-bufferize", - #"func.func(finalizing-bufferize)", - "canonicalize", # Remove dead memrefToTensorOp's - "gradient-postprocess", - # introduced during gradient-bufferize of callbacks - "func.func(buffer-hoisting)", - "func.func(buffer-loop-hoisting)", - "func.func(buffer-deallocation)", - "convert-arraylist-to-memref", - "convert-bufferization-to-memref", - "canonicalize", # Must be after convert-bufferization-to-memref - # otherwise there are issues in lowering of dynamic tensors. - # "cse", - "cp-global-memref", + "one-shot-bufferize{bufferize-function-boundaries}", ] return bufferization From 84da76b4b81de7148a572e898f12a37e16639cc0 Mon Sep 17 00:00:00 2001 From: Tzung-Han Juang Date: Wed, 21 Aug 2024 09:59:48 -0400 Subject: [PATCH 09/49] Add new buffer passes except for the deallocation pipeline --- frontend/catalyst/pipelines.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/frontend/catalyst/pipelines.py b/frontend/catalyst/pipelines.py index 679da05018..19c7f45d42 100644 --- a/frontend/catalyst/pipelines.py +++ b/frontend/catalyst/pipelines.py @@ -220,7 +220,14 @@ def get_quantum_compilation_stage(options: CompileOptions) -> List[str]: def get_bufferization_stage(_options: CompileOptions) -> List[str]: """Returns the list of passes that performs bufferization""" bufferization = [ + "eliminate-empty-tensors", "one-shot-bufferize{bufferize-function-boundaries}", + "func.func(buffer-hoisting)", + "func.func(buffer-loop-hoisting)", + "buffer-results-to-out-params", + "drop-equivalent-buffer-results", + "func.func(promote-buffers-to-stack)", + #"buffer-deallocation-pipeline", ] return bufferization From 0e1b5fe2ac058ef5b1e7042e9f17898e9d458f91 Mon Sep 17 00:00:00 2001 From: Tzung-Han Juang Date: Wed, 21 Aug 2024 12:05:47 -0400 Subject: [PATCH 10/49] Temporarily set side effect of InitOp and FinalizeOp as zero --- mlir/include/Quantum/IR/QuantumOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/include/Quantum/IR/QuantumOps.td b/mlir/include/Quantum/IR/QuantumOps.td index f7ae605df3..1fa76fac94 100644 --- a/mlir/include/Quantum/IR/QuantumOps.td +++ b/mlir/include/Quantum/IR/QuantumOps.td @@ -63,7 +63,7 @@ def NamedObservableAttr : EnumAttr traits = []> : Op; -def InitializeOp : Quantum_Op<"init"> { +def InitializeOp : Quantum_Op<"init", [NoMemoryEffect]> { let summary = "Initialize the quantum runtime."; let assemblyFormat = [{ @@ -71,7 +71,7 @@ def InitializeOp : Quantum_Op<"init"> { }]; } -def FinalizeOp : Quantum_Op<"finalize"> { +def FinalizeOp : Quantum_Op<"finalize", [NoMemoryEffect]> { let summary = "Teardown the quantum runtime."; let assemblyFormat = [{ From 8d49febb85b53efcbaa4e291f4c560ef22df9efa Mon Sep 17 00:00:00 2001 From: Tzung-Han Juang Date: Wed, 21 Aug 2024 15:43:41 -0400 Subject: [PATCH 11/49] Draft Quantum Impl of BufferizableOpInterface --- .../Quantum/Transforms/BufferizableOpInterfaceImpl.h | 12 ++++++++++++ mlir/lib/Quantum/IR/QuantumDialect.cpp | 3 +++ .../Transforms/BufferizableOpInterfaceImpl.cpp | 11 +++++++++++ mlir/lib/Quantum/Transforms/CMakeLists.txt | 1 + 4 files changed, 27 insertions(+) create mode 100644 mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h create mode 100644 mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp diff --git a/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h b/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h new file mode 100644 index 0000000000..069f4b3ee4 --- /dev/null +++ b/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h @@ -0,0 +1,12 @@ +#ifndef MLIR_DIALECT_QUANTUM_BUFFERIZABLEOPINTERFACEIMPL_H +#define MLIR_DIALECT_QUANTUM_BUFFERIZABLEOPINTERFACEIMPL_H + +namespace mlir { +class DialectRegistry; + +namespace tensor { +void registerBufferizableOpInterfaceExternalModels(DialectRegistry ®istry); +} // namespace tensor +} // namespace mlir + +#endif // MLIR_DIALECT_QUANTUM_BUFFERIZABLEOPINTERFACEIMPL_H \ No newline at end of file diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index 385f4e0ae5..04bfe34f2c 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h" #include "mlir/IR/DialectImplementation.h" // needed for generated type parser #include "llvm/ADT/TypeSwitch.h" // needed for generated type parser @@ -43,6 +44,8 @@ void QuantumDialect::initialize() #define GET_OP_LIST #include "Quantum/IR/QuantumOps.cpp.inc" >(); + + declarePromisedInterfaces(); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp new file mode 100644 index 0000000000..a92aa1da79 --- /dev/null +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -0,0 +1,11 @@ +#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h" + +#include "Quantum/IR/QuantumOps.h" +#include "Quantum/Transforms/BufferizableOpInterfaceImpl.h" + +using namespace mlir; +using namespace catalyst::quantum; + +namespace { + +} \ No newline at end of file diff --git a/mlir/lib/Quantum/Transforms/CMakeLists.txt b/mlir/lib/Quantum/Transforms/CMakeLists.txt index d983a23eb9..ed0e22d885 100644 --- a/mlir/lib/Quantum/Transforms/CMakeLists.txt +++ b/mlir/lib/Quantum/Transforms/CMakeLists.txt @@ -1,6 +1,7 @@ set(LIBRARY_NAME quantum-transforms) file(GLOB SRC + BufferizableOpInterfaceImpl.cpp BufferizationPatterns.cpp quantum_bufferize.cpp ConversionPatterns.cpp From 0e70f99281f57cddc63bc25403e91a024252cad1 Mon Sep 17 00:00:00 2001 From: Tzung-Han Juang Date: Wed, 21 Aug 2024 17:53:28 -0400 Subject: [PATCH 12/49] Add empty one-shot-bufferize for quantum::ExtractOp --- .../Transforms/BufferizableOpInterfaceImpl.h | 19 +++++----- .../BufferizableOpInterfaceImpl.cpp | 36 +++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h b/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h index 069f4b3ee4..bf60013f70 100644 --- a/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h +++ b/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h @@ -1,12 +1,13 @@ -#ifndef MLIR_DIALECT_QUANTUM_BUFFERIZABLEOPINTERFACEIMPL_H -#define MLIR_DIALECT_QUANTUM_BUFFERIZABLEOPINTERFACEIMPL_H +#pragma once -namespace mlir { -class DialectRegistry; +using namespace mlir; -namespace tensor { -void registerBufferizableOpInterfaceExternalModels(DialectRegistry ®istry); -} // namespace tensor -} // namespace mlir +namespace catalyst { -#endif // MLIR_DIALECT_QUANTUM_BUFFERIZABLEOPINTERFACEIMPL_H \ No newline at end of file +namespace quantum { + +void registerBufferizableOpInterfaceExternalModels(mlir::DialectRegistry ®istry); + +} + +} // namespace catalyst diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index a92aa1da79..f3dbb521e2 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -1,3 +1,4 @@ +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h" #include "Quantum/IR/QuantumOps.h" @@ -8,4 +9,39 @@ using namespace catalyst::quantum; namespace { +/// Bufferization of tensor.extract. Replace with memref.load. +struct ExtractOpInterface + : public mlir::bufferization::BufferizableOpInterface::ExternalModel { + bool bufferizesToMemoryRead(mlir::Operation *op, mlir::OpOperand &opOperand, + const mlir::bufferization::AnalysisState &state) const { + return true; + } + + bool bufferizesToMemoryWrite(mlir::Operation *op, mlir::OpOperand &opOperand, + const mlir::bufferization::AnalysisState &state) const { + return false; + } + + mlir::bufferization::AliasingValueList getAliasingValues(mlir::Operation *op, + mlir::OpOperand &opOperand, + const mlir::bufferization::AnalysisState &state) const { + return {}; + } + + LogicalResult bufferize(mlir::Operation *op, RewriterBase &rewriter, + const mlir::bufferization::BufferizationOptions &options) const { + auto extractOp = cast(op); + + return success(); + } +}; + +} + +void catalyst::quantum::registerBufferizableOpInterfaceExternalModels( + DialectRegistry ®istry) { + registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { + ExtractOp::attachInterface(*ctx); + }); } \ No newline at end of file From 8283274b249704e1894e563a49ba69fa2a1aab26 Mon Sep 17 00:00:00 2001 From: Erick Ochoa Lopez Date: Tue, 22 Apr 2025 12:54:16 +0000 Subject: [PATCH 13/49] unused variable --- mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index f3dbb521e2..c4c44281d8 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -31,7 +31,7 @@ struct ExtractOpInterface LogicalResult bufferize(mlir::Operation *op, RewriterBase &rewriter, const mlir::bufferization::BufferizationOptions &options) const { - auto extractOp = cast(op); + //auto extractOp = cast(op); return success(); } @@ -44,4 +44,4 @@ void catalyst::quantum::registerBufferizableOpInterfaceExternalModels( registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { ExtractOp::attachInterface(*ctx); }); -} \ No newline at end of file +} From ec9541766b64f8f968bed8b8473867b56e890c82 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 11:05:58 -0400 Subject: [PATCH 14/49] revert llvm/mhlo version to current; let's deal with bufferization first before updating mlir The current mlir version we track already has the new bufferization interface The old interface is just deprecated. We migrate bufferization before dealing with all the other versioning updates. --- .dep-versions | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.dep-versions b/.dep-versions index 2e17e57aaf..3a4bb3cff6 100644 --- a/.dep-versions +++ b/.dep-versions @@ -1,7 +1,7 @@ # Always update the version check in catalyst.__init__ when changing the JAX version. jax=0.4.28 -mhlo=39c37c43fb9db18144f2e155a0fe65864646a968 -llvm=6f2c61071c274a1b5e212e6ad4114641ec7c7fc3 +mhlo=89a891c986650c33df76885f5620e0a92150d90f +llvm=3a8316216807d64a586b971f51695e23883331f7 enzyme=v0.0.149 # Always remove custom PL/LQ versions before release. From 65642ba893a41180eabf3107aafeb2cf5c60a51b Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 11:11:03 -0400 Subject: [PATCH 15/49] .dep_versions EOF new line --- .dep-versions | 1 - 1 file changed, 1 deletion(-) diff --git a/.dep-versions b/.dep-versions index 3a4bb3cff6..b224a7f56f 100644 --- a/.dep-versions +++ b/.dep-versions @@ -13,4 +13,3 @@ pennylane=0.41.0-dev56 # For a custom LQ/LK version, update the package version here and at # 'doc/requirements.txt' lightning=0.41.0-dev22 - From 823e23f31733780a4bac6e4370120b855490f2bd Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 11:13:22 -0400 Subject: [PATCH 16/49] revert TopologicalSortUtils.h location --- mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp b/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp index 4d37ae810e..f389b0d14c 100644 --- a/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp +++ b/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp @@ -15,8 +15,8 @@ #define DEBUG_TYPE "commute_ppr" #include "llvm/Support/Debug.h" - -#include "mlir/Analysis/TopologicalSortUtils.h" +//#include "mlir/Analysis/TopologicalSortUtils.h" +#include "mlir/Transforms/TopologicalSortUtils.h" #include "QEC/IR/QECDialect.h" #include "QEC/IR/QECOpInterfaces.h" From a0de2804bf1a08d9381657b5a102e9dcd5d25e80 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 11:15:59 -0400 Subject: [PATCH 17/49] restore llvm and mhlo version: source files --- mlir/llvm-project | 2 +- mlir/mlir-hlo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/llvm-project b/mlir/llvm-project index 6f2c61071c..3a83162168 160000 --- a/mlir/llvm-project +++ b/mlir/llvm-project @@ -1 +1 @@ -Subproject commit 6f2c61071c274a1b5e212e6ad4114641ec7c7fc3 +Subproject commit 3a8316216807d64a586b971f51695e23883331f7 diff --git a/mlir/mlir-hlo b/mlir/mlir-hlo index 39c37c43fb..89a891c986 160000 --- a/mlir/mlir-hlo +++ b/mlir/mlir-hlo @@ -1 +1 @@ -Subproject commit 39c37c43fb9db18144f2e155a0fe65864646a968 +Subproject commit 89a891c986650c33df76885f5620e0a92150d90f From 26e6e248cdfede064e55d5f1a36d429793cf88c9 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 11:16:45 -0400 Subject: [PATCH 18/49] restore another topological sort location --- mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp b/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp index 187a9bac4d..5ae2b556d4 100644 --- a/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp +++ b/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp @@ -13,11 +13,12 @@ // limitations under the License. #define DEBUG_TYPE "ppr_to_ppm" + #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" - #include "mlir/Analysis/SliceAnalysis.h" -#include "mlir/Analysis/TopologicalSortUtils.h" +//#include "mlir/Analysis/TopologicalSortUtils.h" +#include "mlir/Transforms/TopologicalSortUtils.h" #include "QEC/IR/QECDialect.h" #include "QEC/IR/QECOpInterfaces.h" From 7005ed9e4ab2a70e49e7751b4b3c6fadb01e7926 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 11:19:29 -0400 Subject: [PATCH 19/49] restore `disableVerification` in CompilerDriver.cpp --- mlir/lib/Driver/CompilerDriver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Driver/CompilerDriver.cpp b/mlir/lib/Driver/CompilerDriver.cpp index 20baeef95b..2824bda43e 100644 --- a/mlir/lib/Driver/CompilerDriver.cpp +++ b/mlir/lib/Driver/CompilerDriver.cpp @@ -732,10 +732,10 @@ LogicalResult QuantumDriverMain(const CompilerOptions &options, CompilerOutput & if (runTranslate && (inType == InputType::MLIR)) { TimingScope translateTiming = timing.nest("Translate"); // TODO: Change to true for release. - bool disableVerification = false; + //bool disableVerification = false; llvmModule = timer::timer(translateModuleToLLVMIR, "translateModuleToLLVMIR", - /* add_endl */ false, *mlirModule, llvmContext, "LLVMDialectModule", disableVerification); + /* add_endl */ false, *mlirModule, llvmContext, "LLVMDialectModule");//, disableVerification); if (!llvmModule) { CO_MSG(options, Verbosity::Urgent, "Failed to translate LLVM module\n"); return failure(); From a5a99d1942070f2192dbe6cef6d19f9dd2b41534 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 13:41:05 -0400 Subject: [PATCH 20/49] add buffer interface for quantum.set_state op --- mlir/lib/Quantum/IR/QuantumDialect.cpp | 2 +- .../BufferizableOpInterfaceImpl.cpp | 120 +++++++++++++----- mlir/tools/quantum-opt/quantum-opt.cpp | 3 + 3 files changed, 92 insertions(+), 33 deletions(-) diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index 04bfe34f2c..d96fecda2e 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -45,7 +45,7 @@ void QuantumDialect::initialize() #include "Quantum/IR/QuantumOps.cpp.inc" >(); - declarePromisedInterfaces(); + declarePromisedInterfaces(); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index c4c44281d8..cd98a8c586 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -1,5 +1,20 @@ -#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +// Copyright 2024-2025 Xanadu Quantum Technologies Inc. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h" +#include "mlir/Dialect/Bufferization/IR/Bufferization.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "Quantum/IR/QuantumOps.h" #include "Quantum/Transforms/BufferizableOpInterfaceImpl.h" @@ -10,38 +25,79 @@ using namespace catalyst::quantum; namespace { /// Bufferization of tensor.extract. Replace with memref.load. -struct ExtractOpInterface - : public mlir::bufferization::BufferizableOpInterface::ExternalModel { - bool bufferizesToMemoryRead(mlir::Operation *op, mlir::OpOperand &opOperand, - const mlir::bufferization::AnalysisState &state) const { - return true; - } - - bool bufferizesToMemoryWrite(mlir::Operation *op, mlir::OpOperand &opOperand, - const mlir::bufferization::AnalysisState &state) const { - return false; - } - - mlir::bufferization::AliasingValueList getAliasingValues(mlir::Operation *op, - mlir::OpOperand &opOperand, - const mlir::bufferization::AnalysisState &state) const { - return {}; - } - - LogicalResult bufferize(mlir::Operation *op, RewriterBase &rewriter, - const mlir::bufferization::BufferizationOptions &options) const { - //auto extractOp = cast(op); - - return success(); - } +// struct ExtractOpInterface +// : public mlir::bufferization::BufferizableOpInterface::ExternalModel { +// bool bufferizesToMemoryRead(mlir::Operation *op, mlir::OpOperand &opOperand, +// const mlir::bufferization::AnalysisState &state) const { +// return true; +// } + +// bool bufferizesToMemoryWrite(mlir::Operation *op, mlir::OpOperand &opOperand, +// const mlir::bufferization::AnalysisState &state) const { +// return false; +// } + +// mlir::bufferization::AliasingValueList getAliasingValues(mlir::Operation *op, +// mlir::OpOperand &opOperand, +// const mlir::bufferization::AnalysisState &state) const { +// return {}; +// } + +// LogicalResult bufferize(mlir::Operation *op, RewriterBase &rewriter, +// const mlir::bufferization::BufferizationOptions &options) const { +// //auto extractOp = cast(op); + +// return success(); +// } +// }; + +/// Bufferization of catalyst.quantum.set_state. Convert InState into memref. +struct SetStateOpInterface : public mlir::bufferization::BufferizableOpInterface::ExternalModel< + SetStateOpInterface, catalyst::quantum::SetStateOp> { + bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return true; + } + + bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bufferization::AliasingValueList + getAliasingValues(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return {}; + } + + LogicalResult bufferize(Operation *op, RewriterBase &rewriter, + const bufferization::BufferizationOptions &options) const + { + auto setStateOp = cast(op); + Location loc = op->getLoc(); + auto tensorType = cast(setStateOp.getInState().getType()); + MemRefType memrefType = MemRefType::get(tensorType.getShape(), tensorType.getElementType()); + + auto toMemrefOp = + rewriter.create(loc, memrefType, setStateOp.getInState()); + auto memref = toMemrefOp.getResult(); + auto newSetStateOp = rewriter.create(loc, setStateOp.getOutQubits().getTypes(), + memref, setStateOp.getInQubits()); + bufferization::replaceOpWithBufferizedValues(rewriter, op, newSetStateOp.getOutQubits()); + return success(); + } }; -} +} // namespace -void catalyst::quantum::registerBufferizableOpInterfaceExternalModels( - DialectRegistry ®istry) { - registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { - ExtractOp::attachInterface(*ctx); - }); +void catalyst::quantum::registerBufferizableOpInterfaceExternalModels(DialectRegistry ®istry) +{ + registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { + // ExtractOp::attachInterface(*ctx); + SetStateOp::attachInterface(*ctx); + }); } diff --git a/mlir/tools/quantum-opt/quantum-opt.cpp b/mlir/tools/quantum-opt/quantum-opt.cpp index d6491441fb..6bcc05e15d 100644 --- a/mlir/tools/quantum-opt/quantum-opt.cpp +++ b/mlir/tools/quantum-opt/quantum-opt.cpp @@ -33,6 +33,7 @@ #include "Mitigation/Transforms/Passes.h" #include "QEC/IR/QECDialect.h" #include "Quantum/IR/QuantumDialect.h" +#include "Quantum/Transforms/BufferizableOpInterfaceImpl.h" #include "Quantum/Transforms/Passes.h" namespace test { @@ -59,6 +60,8 @@ int main(int argc, char **argv) registry.insert(); registry.insert(); + catalyst::quantum::registerBufferizableOpInterfaceExternalModels(registry); + return mlir::asMainReturnCode( mlir::MlirOptMain(argc, argv, "Quantum optimizer driver\n", registry)); } From fee74cd97bebd141f00e751c0f57601a95fa1f47 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 13:41:56 -0400 Subject: [PATCH 21/49] add buffer_play.mlir playground for exhibition --- mlir/test/Quantum/buffer_play.mlir | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 mlir/test/Quantum/buffer_play.mlir diff --git a/mlir/test/Quantum/buffer_play.mlir b/mlir/test/Quantum/buffer_play.mlir new file mode 100644 index 0000000000..c418461bed --- /dev/null +++ b/mlir/test/Quantum/buffer_play.mlir @@ -0,0 +1,30 @@ +// RUN: echo "hello world!" +// ../../build/bin/quantum-opt buffer_play.mlir --one-shot-bufferize +module @set_state { + func.func @foo(%arg0: tensor<2xcomplex>, %q0 : !quantum.bit) { + // COM: old CHECK: quantum.set_state(%{{.*}}) %{{.*}} : (memref<2xcomplex>, !quantum.bit) -> !quantum.bit + %0 = quantum.set_state(%arg0) %q0 : (tensor<2xcomplex>, !quantum.bit) -> !quantum.bit + return + } +} + + +// expected: +// module @set_state { +// func.func @foo(%arg0: tensor<2xcomplex>, %arg1: !quantum.bit) { +// %0 = bufferization.to_memref %arg0 : memref<2xcomplex> +// %1 = bufferization.to_memref %arg0 : memref<2xcomplex> +// %2 = quantum.set_state(%1) %arg1 : (memref<2xcomplex>, !quantum.bit) -> !quantum.bit +// return +// } +// } + +// got: (at a5a99d1942070f2192dbe6cef6d19f9dd2b41534) +// module @set_state { +// func.func @foo(%arg0: tensor<2xcomplex>, %arg1: !quantum.bit) { +// %0 = bufferization.to_memref %arg0 : memref<2xcomplex> +// %1 = quantum.set_state(%0) %arg1 : (memref<2xcomplex>, !quantum.bit) -> !quantum.bit +// return +// } +// } + From c006d6af82ad819a466b2c299ad38ffb10f48a56 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 13:56:35 -0400 Subject: [PATCH 22/49] add bufferization for set_basis_state --- mlir/lib/Quantum/IR/QuantumDialect.cpp | 3 +- .../BufferizableOpInterfaceImpl.cpp | 77 +++++++++++-------- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index d96fecda2e..20a7cd2dd0 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -45,7 +45,8 @@ void QuantumDialect::initialize() #include "Quantum/IR/QuantumOps.cpp.inc" >(); - declarePromisedInterfaces(); + declarePromisedInterfaces(); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index cd98a8c586..e5055ee6ea 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -20,41 +20,15 @@ #include "Quantum/Transforms/BufferizableOpInterfaceImpl.h" using namespace mlir; +using namespace mlir::bufferization; using namespace catalyst::quantum; namespace { -/// Bufferization of tensor.extract. Replace with memref.load. -// struct ExtractOpInterface -// : public mlir::bufferization::BufferizableOpInterface::ExternalModel { -// bool bufferizesToMemoryRead(mlir::Operation *op, mlir::OpOperand &opOperand, -// const mlir::bufferization::AnalysisState &state) const { -// return true; -// } - -// bool bufferizesToMemoryWrite(mlir::Operation *op, mlir::OpOperand &opOperand, -// const mlir::bufferization::AnalysisState &state) const { -// return false; -// } - -// mlir::bufferization::AliasingValueList getAliasingValues(mlir::Operation *op, -// mlir::OpOperand &opOperand, -// const mlir::bufferization::AnalysisState &state) const { -// return {}; -// } - -// LogicalResult bufferize(mlir::Operation *op, RewriterBase &rewriter, -// const mlir::bufferization::BufferizationOptions &options) const { -// //auto extractOp = cast(op); - -// return success(); -// } -// }; - /// Bufferization of catalyst.quantum.set_state. Convert InState into memref. -struct SetStateOpInterface : public mlir::bufferization::BufferizableOpInterface::ExternalModel< - SetStateOpInterface, catalyst::quantum::SetStateOp> { +struct SetStateOpInterface + : public bufferization::BufferizableOpInterface::ExternalModel { bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, const bufferization::AnalysisState &state) const { @@ -92,12 +66,53 @@ struct SetStateOpInterface : public mlir::bufferization::BufferizableOpInterface } }; +/// Bufferization of catalyst.quantum.set_basis_state. Convert BasisState into memref. +struct SetBasisStateOpInterface + : public bufferization::BufferizableOpInterface::ExternalModel { + bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return true; + } + + bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bufferization::AliasingValueList + getAliasingValues(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return {}; + } + + LogicalResult bufferize(Operation *op, RewriterBase &rewriter, + const bufferization::BufferizationOptions &options) const + { + auto setBasisStateOp = cast(op); + Location loc = op->getLoc(); + auto tensorType = cast(setBasisStateOp.getBasisState().getType()); + MemRefType memrefType = MemRefType::get(tensorType.getShape(), tensorType.getElementType()); + + auto toMemrefOp = rewriter.create( + loc, memrefType, setBasisStateOp.getBasisState()); + auto memref = toMemrefOp.getResult(); + auto newSetStateOp = rewriter.create( + loc, setBasisStateOp.getOutQubits().getTypes(), memref, setBasisStateOp.getInQubits()); + bufferization::replaceOpWithBufferizedValues(rewriter, op, newSetStateOp.getOutQubits()); + return success(); + } +}; + } // namespace void catalyst::quantum::registerBufferizableOpInterfaceExternalModels(DialectRegistry ®istry) { registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { - // ExtractOp::attachInterface(*ctx); SetStateOp::attachInterface(*ctx); + SetBasisStateOp::attachInterface(*ctx); }); } From cf08821ae78a2f21627462e1c6a635c7b60e1614 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 14:57:03 -0400 Subject: [PATCH 23/49] do stateop --- mlir/lib/Quantum/IR/QuantumDialect.cpp | 2 +- .../BufferizableOpInterfaceImpl.cpp | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index 20a7cd2dd0..e7601504f0 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -45,7 +45,7 @@ void QuantumDialect::initialize() #include "Quantum/IR/QuantumOps.cpp.inc" >(); - declarePromisedInterfaces(); } diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index e5055ee6ea..2c557fab85 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -14,7 +14,9 @@ #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h" #include "mlir/Dialect/Bufferization/IR/Bufferization.h" +#include "mlir/Dialect/Index/IR/IndexOps.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/Dialect/MemRef/IR/MemRef.h" #include "Quantum/IR/QuantumOps.h" #include "Quantum/Transforms/BufferizableOpInterfaceImpl.h" @@ -25,6 +27,56 @@ using namespace catalyst::quantum; namespace { +/// Bufferization of catalyst.quantum.state. Replace with memref.alloc and a new +/// catalyst.quantum.state that uses the memory allocated by memref.alloc. +struct StateOpInterface + : public bufferization::BufferizableOpInterface::ExternalModel { + bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bufferization::AliasingValueList + getAliasingValues(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return {}; + } + + LogicalResult bufferize(Operation *op, RewriterBase &rewriter, + const bufferization::BufferizationOptions &options) const + { + auto stateOp = cast(op); + Location loc = op->getLoc(); + auto tensorType = cast(stateOp.getState().getType()); + MemRefType resultType = MemRefType::get(tensorType.getShape(), tensorType.getElementType()); + + Value buffer; + auto shape = cast(tensorType).getShape(); + if (shape[0] == ShapedType::kDynamic) { + auto indexCastOp = rewriter.create(loc, rewriter.getIndexType(), + stateOp.getDynamicShape()); + buffer = rewriter.create(loc, resultType, ValueRange{indexCastOp}); + } + else { + buffer = rewriter.create(loc, resultType); + } + + auto allocedStateOp = + rewriter.create(loc, TypeRange{}, ValueRange{stateOp.getObs(), buffer}); + allocedStateOp->setAttr("operandSegmentSizes", rewriter.getDenseI32ArrayAttr({1, 0, 1})); + bufferization::replaceOpWithBufferizedValues(rewriter, op, buffer); + return success(); + } +}; + /// Bufferization of catalyst.quantum.set_state. Convert InState into memref. struct SetStateOpInterface : public bufferization::BufferizableOpInterface::ExternalModel(*ctx); SetStateOp::attachInterface(*ctx); SetBasisStateOp::attachInterface(*ctx); }); From 108f5be7e436686ed1906ecd74af9841b1f6a0c5 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 15:14:02 -0400 Subject: [PATCH 24/49] probs op --- mlir/lib/Quantum/IR/QuantumDialect.cpp | 2 +- .../BufferizableOpInterfaceImpl.cpp | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index e7601504f0..81dadecb45 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -45,7 +45,7 @@ void QuantumDialect::initialize() #include "Quantum/IR/QuantumOps.cpp.inc" >(); - declarePromisedInterfaces(); } diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index 2c557fab85..a23f4d3cee 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -27,6 +27,56 @@ using namespace catalyst::quantum; namespace { +/// Bufferization of catalyst.quantum.probs. Replace with memref.alloc and a new +/// catalyst.quantum.probs that uses the memory allocated by memref.alloc. +struct ProbsOpInterface + : public bufferization::BufferizableOpInterface::ExternalModel { + bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bufferization::AliasingValueList + getAliasingValues(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return {}; + } + + LogicalResult bufferize(Operation *op, RewriterBase &rewriter, + const bufferization::BufferizationOptions &options) const + { + auto probsOp = cast(op); + Location loc = op->getLoc(); + auto tensorType = cast(probsOp.getProbabilities().getType()); + MemRefType resultType = MemRefType::get(tensorType.getShape(), tensorType.getElementType()); + + Value buffer; + auto shape = cast(tensorType).getShape(); + if (shape[0] == ShapedType::kDynamic) { + auto indexCastOp = rewriter.create(loc, rewriter.getIndexType(), + probsOp.getDynamicShape()); + buffer = rewriter.create(loc, resultType, ValueRange{indexCastOp}); + } + else { + buffer = rewriter.create(loc, resultType); + } + + auto allocedProbsOp = + rewriter.create(loc, TypeRange{}, ValueRange{probsOp.getObs(), buffer}); + allocedProbsOp->setAttr("operandSegmentSizes", rewriter.getDenseI32ArrayAttr({1, 0, 1})); + bufferization::replaceOpWithBufferizedValues(rewriter, op, buffer); + return success(); + } +}; + /// Bufferization of catalyst.quantum.state. Replace with memref.alloc and a new /// catalyst.quantum.state that uses the memory allocated by memref.alloc. struct StateOpInterface @@ -164,6 +214,7 @@ struct SetBasisStateOpInterface void catalyst::quantum::registerBufferizableOpInterfaceExternalModels(DialectRegistry ®istry) { registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { + ProbsOp::attachInterface(*ctx); StateOp::attachInterface(*ctx); SetStateOp::attachInterface(*ctx); SetBasisStateOp::attachInterface(*ctx); From 93b25d3c78f5a52062cb88a892931e0df1fb0e5e Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 15:37:33 -0400 Subject: [PATCH 25/49] sample op --- mlir/lib/Quantum/IR/QuantumDialect.cpp | 4 +- .../BufferizableOpInterfaceImpl.cpp | 65 +++++++++++++++++-- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index 81dadecb45..875d4f76e6 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -45,8 +45,8 @@ void QuantumDialect::initialize() #include "Quantum/IR/QuantumOps.cpp.inc" >(); - declarePromisedInterfaces(); + declarePromisedInterfaces(); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index a23f4d3cee..31303ed403 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -27,8 +27,57 @@ using namespace catalyst::quantum; namespace { -/// Bufferization of catalyst.quantum.probs. Replace with memref.alloc and a new -/// catalyst.quantum.probs that uses the memory allocated by memref.alloc. +// Bufferization of quantum.sample. +// Result tensor of quantum.sample is bufferized with a corresponding memref.alloc. +// Users of the result tensor are updated to use the new memref. +struct SampleOpInterface + : public bufferization::BufferizableOpInterface::ExternalModel { + bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bufferization::AliasingValueList + getAliasingValues(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return {}; + } + + LogicalResult bufferize(Operation *op, RewriterBase &rewriter, + const bufferization::BufferizationOptions &options) const + { + auto sampleOp = cast(op); + Location loc = op->getLoc(); + auto tensorType = cast(sampleOp.getSamples().getType()); + MemRefType resultType = MemRefType::get(tensorType.getShape(), tensorType.getElementType()); + + SmallVector allocSizes; + for (Value dynShapeDimension : sampleOp.getDynamicShape()) { + auto indexCastOp = + rewriter.create(loc, rewriter.getIndexType(), dynShapeDimension); + allocSizes.push_back(indexCastOp); + } + + Value allocVal = rewriter.create(loc, resultType, allocSizes); + auto allocedSampleOp = rewriter.create( + loc, TypeRange{}, ValueRange{sampleOp.getObs(), allocVal}, op->getAttrs()); + allocedSampleOp->setAttr("operandSegmentSizes", rewriter.getDenseI32ArrayAttr({1, 0, 1})); + bufferization::replaceOpWithBufferizedValues(rewriter, op, allocVal); + return success(); + } +}; + +// Bufferization of quantum.probs. +// Result tensor of quantum.probs is bufferized with a corresponding memref.alloc. +// Users of the result tensor are updated to use the new memref. struct ProbsOpInterface : public bufferization::BufferizableOpInterface::ExternalModel { bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, @@ -77,8 +126,9 @@ struct ProbsOpInterface } }; -/// Bufferization of catalyst.quantum.state. Replace with memref.alloc and a new -/// catalyst.quantum.state that uses the memory allocated by memref.alloc. +// Bufferization of quantum.state. +// Result tensor of quantum.state is bufferized with a corresponding memref.alloc. +// Users of the result tensor are updated to use the new memref. struct StateOpInterface : public bufferization::BufferizableOpInterface::ExternalModel { bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, @@ -127,7 +177,8 @@ struct StateOpInterface } }; -/// Bufferization of catalyst.quantum.set_state. Convert InState into memref. +// Bufferization of quantum.set_state. +// Convert InState into memref. struct SetStateOpInterface : public bufferization::BufferizableOpInterface::ExternalModel { @@ -168,7 +219,8 @@ struct SetStateOpInterface } }; -/// Bufferization of catalyst.quantum.set_basis_state. Convert BasisState into memref. +// Bufferization of quantum.set_basis_state. +// Convert BasisState into memref. struct SetBasisStateOpInterface : public bufferization::BufferizableOpInterface::ExternalModel { @@ -214,6 +266,7 @@ struct SetBasisStateOpInterface void catalyst::quantum::registerBufferizableOpInterfaceExternalModels(DialectRegistry ®istry) { registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { + SampleOp::attachInterface(*ctx); ProbsOp::attachInterface(*ctx); StateOp::attachInterface(*ctx); SetStateOp::attachInterface(*ctx); From a61a151bdc3f369a78f7421996b6d88a96930c90 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 16:00:41 -0400 Subject: [PATCH 26/49] counts op --- mlir/lib/Quantum/IR/QuantumDialect.cpp | 4 +- .../BufferizableOpInterfaceImpl.cpp | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index 875d4f76e6..6e41649624 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -45,8 +45,8 @@ void QuantumDialect::initialize() #include "Quantum/IR/QuantumOps.cpp.inc" >(); - declarePromisedInterfaces(); + declarePromisedInterfaces(); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index 31303ed403..e1dd8f51ba 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -75,6 +75,64 @@ struct SampleOpInterface } }; +// Bufferization of quantum.counts. +// Result tensors of quantum.counts are bufferized with corresponding memref.alloc ops. +// Users of the result tensors are updated to use the new memrefs. +struct CountsOpInterface + : public bufferization::BufferizableOpInterface::ExternalModel { + bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bufferization::AliasingValueList + getAliasingValues(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return {}; + } + + LogicalResult bufferize(Operation *op, RewriterBase &rewriter, + const bufferization::BufferizationOptions &options) const + { + auto countsOp = cast(op); + Location loc = op->getLoc(); + + SmallVector buffers; + for (size_t i : {0, 1}) { + auto tensorType = cast(countsOp.getType(i)); + MemRefType resultType = + MemRefType::get(tensorType.getShape(), tensorType.getElementType()); + auto shape = cast(tensorType).getShape(); + + Value allocVal; + if (shape[0] == ShapedType::kDynamic) { + auto indexCastOp = rewriter.create(loc, rewriter.getIndexType(), + countsOp.getDynamicShape()); + allocVal = + rewriter.create(loc, resultType, ValueRange{indexCastOp}); + } + else { + allocVal = rewriter.create(loc, resultType); + } + buffers.push_back(allocVal); + } + + rewriter.create(loc, nullptr, nullptr, countsOp.getObs(), nullptr, buffers[0], + buffers[1]); + bufferization::replaceOpWithBufferizedValues(rewriter, op, buffers); + + return success(); + } +}; + // Bufferization of quantum.probs. // Result tensor of quantum.probs is bufferized with a corresponding memref.alloc. // Users of the result tensor are updated to use the new memref. @@ -267,6 +325,7 @@ void catalyst::quantum::registerBufferizableOpInterfaceExternalModels(DialectReg { registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { SampleOp::attachInterface(*ctx); + CountsOp::attachInterface(*ctx); ProbsOp::attachInterface(*ctx); StateOp::attachInterface(*ctx); SetStateOp::attachInterface(*ctx); From 1ad56d97d10fae2f6b4dea62796914e267c60200 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 16:02:02 -0400 Subject: [PATCH 27/49] remove buffer_play playground --- mlir/test/Quantum/buffer_play.mlir | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 mlir/test/Quantum/buffer_play.mlir diff --git a/mlir/test/Quantum/buffer_play.mlir b/mlir/test/Quantum/buffer_play.mlir deleted file mode 100644 index c418461bed..0000000000 --- a/mlir/test/Quantum/buffer_play.mlir +++ /dev/null @@ -1,30 +0,0 @@ -// RUN: echo "hello world!" -// ../../build/bin/quantum-opt buffer_play.mlir --one-shot-bufferize -module @set_state { - func.func @foo(%arg0: tensor<2xcomplex>, %q0 : !quantum.bit) { - // COM: old CHECK: quantum.set_state(%{{.*}}) %{{.*}} : (memref<2xcomplex>, !quantum.bit) -> !quantum.bit - %0 = quantum.set_state(%arg0) %q0 : (tensor<2xcomplex>, !quantum.bit) -> !quantum.bit - return - } -} - - -// expected: -// module @set_state { -// func.func @foo(%arg0: tensor<2xcomplex>, %arg1: !quantum.bit) { -// %0 = bufferization.to_memref %arg0 : memref<2xcomplex> -// %1 = bufferization.to_memref %arg0 : memref<2xcomplex> -// %2 = quantum.set_state(%1) %arg1 : (memref<2xcomplex>, !quantum.bit) -> !quantum.bit -// return -// } -// } - -// got: (at a5a99d1942070f2192dbe6cef6d19f9dd2b41534) -// module @set_state { -// func.func @foo(%arg0: tensor<2xcomplex>, %arg1: !quantum.bit) { -// %0 = bufferization.to_memref %arg0 : memref<2xcomplex> -// %1 = quantum.set_state(%0) %arg1 : (memref<2xcomplex>, !quantum.bit) -> !quantum.bit -// return -// } -// } - From c00cc8cc8604c3ec13fa390640c033dcb17f0a5d Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 16:03:25 -0400 Subject: [PATCH 28/49] quantum bufferization lit test uses --one-shot-bufferize --- mlir/test/Quantum/BufferizationTest.mlir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/test/Quantum/BufferizationTest.mlir b/mlir/test/Quantum/BufferizationTest.mlir index 995b92c86c..a489fd5aaf 100644 --- a/mlir/test/Quantum/BufferizationTest.mlir +++ b/mlir/test/Quantum/BufferizationTest.mlir @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// RUN: quantum-opt --quantum-bufferize --split-input-file %s | FileCheck %s +// RUN: quantum-opt --one-shot-bufferize --split-input-file %s | FileCheck %s ////////////////// // Measurements // From 9c2638d7a587a9fb2dadd11acf2203a07c0ddfcd Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 16:12:58 -0400 Subject: [PATCH 29/49] restore pipelines --- frontend/catalyst/pipelines.py | 37 +++++++++++++++++++++++++--------- mlir/lib/Driver/Pipelines.cpp | 10 ++++----- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/frontend/catalyst/pipelines.py b/frontend/catalyst/pipelines.py index 19c7f45d42..eb3a949f1b 100644 --- a/frontend/catalyst/pipelines.py +++ b/frontend/catalyst/pipelines.py @@ -68,9 +68,6 @@ class CompileOptions: disable_assertions (Optional[bool]): disables all assertions. Default is ``False``. seed (Optional[int]) : the seed for random operations in a qjit call. Default is None. - experimental_capture (bool): If set to ``True``, - use PennyLane's experimental program capture capabilities - to capture the function for compilation. circuit_transform_pipeline (Optional[dict[str, dict[str, str]]]): A dictionary that specifies the quantum circuit transformation pass pipeline order, and optionally arguments for each pass in the pipeline. @@ -94,7 +91,6 @@ class CompileOptions: checkpoint_stage: Optional[str] = "" disable_assertions: Optional[bool] = False seed: Optional[int] = None - experimental_capture: Optional[bool] = False circuit_transform_pipeline: Optional[dict[str, dict[str, str]]] = None pass_plugins: Optional[Set[Path]] = None dialect_plugins: Optional[Set[Path]] = None @@ -220,14 +216,35 @@ def get_quantum_compilation_stage(options: CompileOptions) -> List[str]: def get_bufferization_stage(_options: CompileOptions) -> List[str]: """Returns the list of passes that performs bufferization""" bufferization = [ - "eliminate-empty-tensors", - "one-shot-bufferize{bufferize-function-boundaries}", + "one-shot-bufferize{dialect-filter=memref}", + "inline", + "gradient-preprocess", + "gradient-bufferize", + "scf-bufferize", + "convert-tensor-to-linalg", # tensor.pad + "convert-elementwise-to-linalg", # Must be run before --arith-bufferize + "arith-bufferize", + "empty-tensor-to-alloc-tensor", + "func.func(bufferization-bufferize)", + "func.func(tensor-bufferize)", + "catalyst-bufferize", # Must be run before -- func.func(linalg-bufferize) + "func.func(linalg-bufferize)", + "func.func(tensor-bufferize)", + "quantum-bufferize", + "func-bufferize", + "func.func(finalizing-bufferize)", + "canonicalize", # Remove dead memrefToTensorOp's + "gradient-postprocess", + # introduced during gradient-bufferize of callbacks "func.func(buffer-hoisting)", "func.func(buffer-loop-hoisting)", - "buffer-results-to-out-params", - "drop-equivalent-buffer-results", - "func.func(promote-buffers-to-stack)", - #"buffer-deallocation-pipeline", + "func.func(buffer-deallocation)", + "convert-arraylist-to-memref", + "convert-bufferization-to-memref", + "canonicalize", # Must be after convert-bufferization-to-memref + # otherwise there are issues in lowering of dynamic tensors. + # "cse", + "cp-global-memref", ] return bufferization diff --git a/mlir/lib/Driver/Pipelines.cpp b/mlir/lib/Driver/Pipelines.cpp index af0ad8f08d..d1e2dc3eb9 100644 --- a/mlir/lib/Driver/Pipelines.cpp +++ b/mlir/lib/Driver/Pipelines.cpp @@ -72,13 +72,13 @@ void createBufferizationPipeline(OpPassManager &pm) pm.addPass(mlir::createSCFBufferizePass()); pm.addPass(mlir::createConvertTensorToLinalgPass()); pm.addPass(mlir::createConvertElementwiseToLinalgPass()); - //pm.addPass(mlir::arith::createArithBufferizePass()); + pm.addPass(mlir::arith::createArithBufferizePass()); pm.addPass(mlir::bufferization::createEmptyTensorToAllocTensorPass()); - //pm.addNestedPass(mlir::bufferization::createBufferizationBufferizePass()); - //pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); + pm.addNestedPass(mlir::bufferization::createBufferizationBufferizePass()); + pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); pm.addPass(catalyst::createCatalystBufferizationPass()); - //pm.addNestedPass(mlir::createLinalgBufferizePass()); - //pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); + pm.addNestedPass(mlir::createLinalgBufferizePass()); + pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); pm.addPass(catalyst::createQuantumBufferizationPass()); pm.addPass(mlir::func::createFuncBufferizePass()); pm.addNestedPass(mlir::bufferization::createFinalizingBufferizePass()); From 29d2dd8662c62f54f61bc6614f69e69ec43ce3c1 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 16:41:08 -0400 Subject: [PATCH 30/49] register quantum dialect bufferization interface for the main catalyst cli --- frontend/catalyst/pipelines.py | 4 +++- mlir/lib/Driver/CompilerDriver.cpp | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/catalyst/pipelines.py b/frontend/catalyst/pipelines.py index eb3a949f1b..c538a22aba 100644 --- a/frontend/catalyst/pipelines.py +++ b/frontend/catalyst/pipelines.py @@ -216,7 +216,9 @@ def get_quantum_compilation_stage(options: CompileOptions) -> List[str]: def get_bufferization_stage(_options: CompileOptions) -> List[str]: """Returns the list of passes that performs bufferization""" bufferization = [ - "one-shot-bufferize{dialect-filter=memref}", + #"one-shot-bufferize{dialect-filter=memref}", + "eliminate-empty-tensors", + "one-shot-bufferize{bufferize-function-boundaries}", "inline", "gradient-preprocess", "gradient-bufferize", diff --git a/mlir/lib/Driver/CompilerDriver.cpp b/mlir/lib/Driver/CompilerDriver.cpp index a9176335a0..c9546bed07 100644 --- a/mlir/lib/Driver/CompilerDriver.cpp +++ b/mlir/lib/Driver/CompilerDriver.cpp @@ -70,6 +70,7 @@ #include "Mitigation/Transforms/Passes.h" #include "QEC/IR/QECDialect.h" #include "Quantum/IR/QuantumDialect.h" +#include "Quantum/Transforms/BufferizableOpInterfaceImpl.h" #include "Quantum/Transforms/Passes.h" #include "Enzyme.h" @@ -964,6 +965,9 @@ int QuantumDriverMainFromCL(int argc, char **argv) registerAllCatalystDialects(registry); registerLLVMTranslations(registry); + // Register bufferization interfaces + catalyst::quantum::registerBufferizableOpInterfaceExternalModels(registry); + // Register and parse command line options. std::string inputFilename, outputFilename; std::string helpStr = "Catalyst Command Line Interface options. \n" From bfdac152dbb0cf9354899fbc6f996da4e765515c Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 16:50:12 -0400 Subject: [PATCH 31/49] revert `NoMemoryEffect` in quantum.init/finalize --- mlir/include/Quantum/IR/QuantumOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/include/Quantum/IR/QuantumOps.td b/mlir/include/Quantum/IR/QuantumOps.td index 1fa76fac94..50695304b8 100644 --- a/mlir/include/Quantum/IR/QuantumOps.td +++ b/mlir/include/Quantum/IR/QuantumOps.td @@ -63,7 +63,7 @@ def NamedObservableAttr : EnumAttr traits = []> : Op; -def InitializeOp : Quantum_Op<"init", [NoMemoryEffect]> { +def InitializeOp : Quantum_Op<"init"> { //, [NoMemoryEffect]> { let summary = "Initialize the quantum runtime."; let assemblyFormat = [{ @@ -71,7 +71,7 @@ def InitializeOp : Quantum_Op<"init", [NoMemoryEffect]> { }]; } -def FinalizeOp : Quantum_Op<"finalize", [NoMemoryEffect]> { +def FinalizeOp : Quantum_Op<"finalize"> { //, [NoMemoryEffect]> { let summary = "Teardown the quantum runtime."; let assemblyFormat = [{ From 77d4544c96452f2fe0b1bda5045fa907d61b97e8 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Mon, 28 Apr 2025 16:59:08 -0400 Subject: [PATCH 32/49] change quantum-bufferize in py pipeline to one-shot bufferize with filter on quantum dialect --- frontend/catalyst/pipelines.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/frontend/catalyst/pipelines.py b/frontend/catalyst/pipelines.py index c538a22aba..c30cfc8249 100644 --- a/frontend/catalyst/pipelines.py +++ b/frontend/catalyst/pipelines.py @@ -216,9 +216,7 @@ def get_quantum_compilation_stage(options: CompileOptions) -> List[str]: def get_bufferization_stage(_options: CompileOptions) -> List[str]: """Returns the list of passes that performs bufferization""" bufferization = [ - #"one-shot-bufferize{dialect-filter=memref}", - "eliminate-empty-tensors", - "one-shot-bufferize{bufferize-function-boundaries}", + "one-shot-bufferize{dialect-filter=memref}", "inline", "gradient-preprocess", "gradient-bufferize", @@ -232,7 +230,8 @@ def get_bufferization_stage(_options: CompileOptions) -> List[str]: "catalyst-bufferize", # Must be run before -- func.func(linalg-bufferize) "func.func(linalg-bufferize)", "func.func(tensor-bufferize)", - "quantum-bufferize", + #"quantum-bufferize", + "one-shot-bufferize{dialect-filter=quantum}", "func-bufferize", "func.func(finalizing-bufferize)", "canonicalize", # Remove dead memrefToTensorOp's From b963ed70ee71260c464395dbb8faf435ce4b3aa9 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Tue, 29 Apr 2025 10:38:06 -0400 Subject: [PATCH 33/49] qubit unitary op --- mlir/lib/Quantum/IR/QuantumDialect.cpp | 4 +- .../BufferizableOpInterfaceImpl.cpp | 44 +++++++++++++++++++ mlir/test/Quantum/BufferizationTest.mlir | 10 +++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index 6e41649624..74699ad320 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -45,8 +45,8 @@ void QuantumDialect::initialize() #include "Quantum/IR/QuantumOps.cpp.inc" >(); - declarePromisedInterfaces(); + declarePromisedInterfaces(); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index e1dd8f51ba..811c251d95 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -27,6 +27,49 @@ using namespace catalyst::quantum; namespace { +// Bufferization of quantum.unitary. +// Convert Matrix into memref. +struct QubitUnitaryOpInterface + : public bufferization::BufferizableOpInterface::ExternalModel { + bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return true; + } + + bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bufferization::AliasingValueList + getAliasingValues(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return {}; + } + + LogicalResult bufferize(Operation *op, RewriterBase &rewriter, + const bufferization::BufferizationOptions &options) const + { + auto qubitUnitaryOp = cast(op); + Location loc = op->getLoc(); + auto tensorType = cast(qubitUnitaryOp.getMatrix().getType()); + MemRefType memrefType = MemRefType::get(tensorType.getShape(), tensorType.getElementType()); + auto toMemrefOp = + rewriter.create(loc, memrefType, qubitUnitaryOp.getMatrix()); + auto memref = toMemrefOp.getResult(); + bufferization::replaceOpWithNewBufferizedOp( + rewriter, op, qubitUnitaryOp.getOutQubits().getTypes(), + qubitUnitaryOp.getOutCtrlQubits().getTypes(), memref, qubitUnitaryOp.getInQubits(), + qubitUnitaryOp.getAdjointAttr(), qubitUnitaryOp.getInCtrlQubits(), + qubitUnitaryOp.getInCtrlValues()); + return success(); + } +}; + // Bufferization of quantum.sample. // Result tensor of quantum.sample is bufferized with a corresponding memref.alloc. // Users of the result tensor are updated to use the new memref. @@ -324,6 +367,7 @@ struct SetBasisStateOpInterface void catalyst::quantum::registerBufferizableOpInterfaceExternalModels(DialectRegistry ®istry) { registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { + QubitUnitaryOp::attachInterface(*ctx); SampleOp::attachInterface(*ctx); CountsOp::attachInterface(*ctx); ProbsOp::attachInterface(*ctx); diff --git a/mlir/test/Quantum/BufferizationTest.mlir b/mlir/test/Quantum/BufferizationTest.mlir index a489fd5aaf..b3ec0f7b54 100644 --- a/mlir/test/Quantum/BufferizationTest.mlir +++ b/mlir/test/Quantum/BufferizationTest.mlir @@ -14,6 +14,16 @@ // RUN: quantum-opt --one-shot-bufferize --split-input-file %s | FileCheck %s +func.func @qubit_unitary(%q0: !quantum.bit, %matrix: tensor<2x2xcomplex>) { + // CHECK: [[memref:%.+]] = bufferization.to_memref %arg1 : memref<2x2xcomplex> + // CHECK: {{%.+}} = quantum.unitary([[memref]] : memref<2x2xcomplex>) %arg0 : !quantum.bit + %out_qubits = quantum.unitary(%matrix : tensor<2x2xcomplex>) %q0 : !quantum.bit + + func.return +} + +// ----- + ////////////////// // Measurements // ////////////////// From 1f5662b67f9cf16ace0bd4f0eff3a45a86458da2 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Tue, 29 Apr 2025 10:54:11 -0400 Subject: [PATCH 34/49] license --- .../Transforms/BufferizableOpInterfaceImpl.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h b/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h index bf60013f70..ba6e894dac 100644 --- a/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h +++ b/mlir/include/Quantum/Transforms/BufferizableOpInterfaceImpl.h @@ -1,3 +1,17 @@ +// Copyright 2024-2025 Xanadu Quantum Technologies Inc. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #pragma once using namespace mlir; From 5015f7662aa8e315c9216e84c0fce803ae639290 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Tue, 29 Apr 2025 10:54:24 -0400 Subject: [PATCH 35/49] hermitian op --- mlir/lib/Quantum/IR/QuantumDialect.cpp | 4 +- .../BufferizableOpInterfaceImpl.cpp | 43 +++++++++++++++++++ mlir/test/Quantum/BufferizationTest.mlir | 10 +++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index 74699ad320..40871bc466 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -45,8 +45,8 @@ void QuantumDialect::initialize() #include "Quantum/IR/QuantumOps.cpp.inc" >(); - declarePromisedInterfaces(); + declarePromisedInterfaces(); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index 811c251d95..121e88346e 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -70,6 +70,48 @@ struct QubitUnitaryOpInterface } }; +// Bufferization of quantum.hermitian. +// Convert Matrix into memref. +struct HermitianOpInterface + : public bufferization::BufferizableOpInterface::ExternalModel { + bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return true; + } + + bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bufferization::AliasingValueList + getAliasingValues(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return {}; + } + + LogicalResult bufferize(Operation *op, RewriterBase &rewriter, + const bufferization::BufferizationOptions &options) const + { + auto hermitianOp = cast(op); + Location loc = op->getLoc(); + auto tensorType = cast(hermitianOp.getMatrix().getType()); + MemRefType memrefType = MemRefType::get(tensorType.getShape(), tensorType.getElementType()); + auto toMemrefOp = + rewriter.create(loc, memrefType, hermitianOp.getMatrix()); + auto memref = toMemrefOp.getResult(); + auto newHermitianOp = rewriter.create(loc, hermitianOp.getType(), memref, + hermitianOp.getQubits()); + bufferization::replaceOpWithBufferizedValues(rewriter, op, newHermitianOp.getObs()); + + return success(); + } +}; + // Bufferization of quantum.sample. // Result tensor of quantum.sample is bufferized with a corresponding memref.alloc. // Users of the result tensor are updated to use the new memref. @@ -368,6 +410,7 @@ void catalyst::quantum::registerBufferizableOpInterfaceExternalModels(DialectReg { registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { QubitUnitaryOp::attachInterface(*ctx); + HermitianOp::attachInterface(*ctx); SampleOp::attachInterface(*ctx); CountsOp::attachInterface(*ctx); ProbsOp::attachInterface(*ctx); diff --git a/mlir/test/Quantum/BufferizationTest.mlir b/mlir/test/Quantum/BufferizationTest.mlir index b3ec0f7b54..7e89c40c88 100644 --- a/mlir/test/Quantum/BufferizationTest.mlir +++ b/mlir/test/Quantum/BufferizationTest.mlir @@ -24,6 +24,16 @@ func.func @qubit_unitary(%q0: !quantum.bit, %matrix: tensor<2x2xcomplex>) { // ----- +func.func @hermitian(%q0: !quantum.bit, %matrix: tensor<2x2xcomplex>) { + // CHECK: [[memref:%.+]] = bufferization.to_memref %arg1 : memref<2x2xcomplex> + // CHECK: {{%.+}} = quantum.hermitian([[memref]] : memref<2x2xcomplex>) %arg0 : !quantum.obs + %obs = quantum.hermitian(%matrix : tensor<2x2xcomplex>) %q0 : !quantum.obs + + func.return +} + +// ----- + ////////////////// // Measurements // ////////////////// From f14b450418b56363416ee75f68a224c3dfefb7fd Mon Sep 17 00:00:00 2001 From: paul0403 Date: Tue, 29 Apr 2025 11:04:25 -0400 Subject: [PATCH 36/49] hamiltonian op --- mlir/lib/Quantum/IR/QuantumDialect.cpp | 3 +- .../BufferizableOpInterfaceImpl.cpp | 43 +++ mlir/test/Quantum/BufferizationTest.mlir | 300 +++++++++++------- 3 files changed, 229 insertions(+), 117 deletions(-) diff --git a/mlir/lib/Quantum/IR/QuantumDialect.cpp b/mlir/lib/Quantum/IR/QuantumDialect.cpp index 40871bc466..7049f58e63 100644 --- a/mlir/lib/Quantum/IR/QuantumDialect.cpp +++ b/mlir/lib/Quantum/IR/QuantumDialect.cpp @@ -46,7 +46,8 @@ void QuantumDialect::initialize() >(); declarePromisedInterfaces(); + HamiltonianOp, SampleOp, CountsOp, ProbsOp, StateOp, SetStateOp, + SetBasisStateOp>(); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index 121e88346e..f0c3b1f9ad 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -112,6 +112,48 @@ struct HermitianOpInterface } }; +// Bufferization of quantum.hamiltonian. +// Convert coefficient tensor into memref. +struct HamiltonianOpInterface + : public bufferization::BufferizableOpInterface::ExternalModel { + bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return true; + } + + bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return false; + } + + bufferization::AliasingValueList + getAliasingValues(Operation *op, OpOperand &opOperand, + const bufferization::AnalysisState &state) const + { + return {}; + } + + LogicalResult bufferize(Operation *op, RewriterBase &rewriter, + const bufferization::BufferizationOptions &options) const + { + auto hamiltonianOp = cast(op); + Location loc = op->getLoc(); + auto tensorType = cast(hamiltonianOp.getCoeffs().getType()); + MemRefType memrefType = MemRefType::get(tensorType.getShape(), tensorType.getElementType()); + auto toMemrefOp = + rewriter.create(loc, memrefType, hamiltonianOp.getCoeffs()); + auto memref = toMemrefOp.getResult(); + auto newHamiltonianOp = rewriter.create(loc, hamiltonianOp.getType(), memref, + hamiltonianOp.getTerms()); + bufferization::replaceOpWithBufferizedValues(rewriter, op, newHamiltonianOp.getObs()); + + return success(); + } +}; + // Bufferization of quantum.sample. // Result tensor of quantum.sample is bufferized with a corresponding memref.alloc. // Users of the result tensor are updated to use the new memref. @@ -411,6 +453,7 @@ void catalyst::quantum::registerBufferizableOpInterfaceExternalModels(DialectReg registry.addExtension(+[](MLIRContext *ctx, catalyst::quantum::QuantumDialect *dialect) { QubitUnitaryOp::attachInterface(*ctx); HermitianOp::attachInterface(*ctx); + HamiltonianOp::attachInterface(*ctx); SampleOp::attachInterface(*ctx); CountsOp::attachInterface(*ctx); ProbsOp::attachInterface(*ctx); diff --git a/mlir/test/Quantum/BufferizationTest.mlir b/mlir/test/Quantum/BufferizationTest.mlir index 7e89c40c88..a103540f2c 100644 --- a/mlir/test/Quantum/BufferizationTest.mlir +++ b/mlir/test/Quantum/BufferizationTest.mlir @@ -14,142 +14,210 @@ // RUN: quantum-opt --one-shot-bufferize --split-input-file %s | FileCheck %s -func.func @qubit_unitary(%q0: !quantum.bit, %matrix: tensor<2x2xcomplex>) { +func.func @qubit_unitary(% q0 + : !quantum.bit, % matrix + : tensor < 2x2xcomplex < f64 >>){ // CHECK: [[memref:%.+]] = bufferization.to_memref %arg1 : memref<2x2xcomplex> // CHECK: {{%.+}} = quantum.unitary([[memref]] : memref<2x2xcomplex>) %arg0 : !quantum.bit - %out_qubits = quantum.unitary(%matrix : tensor<2x2xcomplex>) %q0 : !quantum.bit + % out_qubits = quantum.unitary(% matrix + : tensor < 2x2xcomplex < f64 >>) % + q0 : !quantum + .bit - func.return + func.return } // ----- -func.func @hermitian(%q0: !quantum.bit, %matrix: tensor<2x2xcomplex>) { +func.func @hermitian(% q0 + : !quantum.bit, % matrix + : tensor < 2x2xcomplex < f64 >>){ // CHECK: [[memref:%.+]] = bufferization.to_memref %arg1 : memref<2x2xcomplex> - // CHECK: {{%.+}} = quantum.hermitian([[memref]] : memref<2x2xcomplex>) %arg0 : !quantum.obs - %obs = quantum.hermitian(%matrix : tensor<2x2xcomplex>) %q0 : !quantum.obs - - func.return + // CHECK: {{%.+}} = quantum.hermitian([[memref]] : memref<2x2xcomplex>) %arg0 : + // !quantum.obs + % obs = quantum.hermitian(% matrix + : tensor < 2x2xcomplex < f64 >>) % + q0 : !quantum + .obs + + func.return } // ----- -////////////////// -// Measurements // -////////////////// - -func.func @counts(%q0: !quantum.bit, %q1: !quantum.bit, %c : i64) { - %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs - - // CHECK: [[eigval_alloc:%.+]] = memref.alloc() : memref<4xf64> - // CHECK: [[counts_alloc:%.+]] = memref.alloc() : memref<4xi64> - // CHECK: quantum.counts {{.*}} in([[eigval_alloc]] : memref<4xf64>, [[counts_alloc]] : memref<4xi64>) - %static_counts:2 = quantum.counts %obs : tensor<4xf64>, tensor<4xi64> - - // CHECK: [[idx1:%.+]] = index.casts %arg2 : i64 to index - // CHECK: [[alloc1:%.+]] = memref.alloc([[idx1]]) : memref - // CHECK: [[idx2:%.+]] = index.casts %arg2 : i64 to index - // CHECK: [[alloc2:%.+]] = memref.alloc([[idx2]]) : memref - // CHECK: quantum.counts {{.*}} in([[alloc1]] : memref, [[alloc2]] : memref) - %dyn_counts:2 = quantum.counts %obs shape %c : tensor, tensor - - func.return +func.func @hamiltonian(% obs + : !quantum.obs, % coeffs + : tensor<1xf64>){ + // CHECK: [[memref:%.+]] = bufferization.to_memref %arg1 : memref<1xf64> + // CHECK: {{%.+}} = quantum.hamiltonian([[memref]] : memref<1xf64>) %arg0 : !quantum.obs + % hamil = quantum.hamiltonian(% coeffs + : tensor<1xf64>) % + obs : !quantum + .obs + + func.return } // ----- -func.func @sample(%c1 : i64, %c2 : i64, %q0: !quantum.bit, %q1: !quantum.bit, %dyn_shots: i64) { - %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs - - // CHECK: [[idx1:%.+]] = index.casts %arg0 : i64 to index - // CHECK: [[alloc1:%.+]] = memref.alloc([[idx1]]) : memref - // CHECK: quantum.sample {{.*}} in([[alloc1]] : memref) - %samples_dyn1 = quantum.sample %obs shape %c1: tensor - - // CHECK: [[idx2:%.+]] = index.casts %arg1 : i64 to index - // CHECK: [[alloc2:%.+]] = memref.alloc([[idx2]]) : memref<42x?xf64> - // CHECK: quantum.sample {{.*}} in([[alloc2]] : memref<42x?xf64>) - %samples_dyn2 = quantum.sample %obs shape %c2 : tensor<42x?xf64> - - // CHECK: [[alloc_static:%.+]] = memref.alloc() : memref<10x2xf64> - // CHECK: quantum.sample {{.*}} in([[alloc_static]] : memref<10x2xf64>) - %samples_static = quantum.sample %obs : tensor<10x2xf64> - - // CHECK: [[idx3:%.+]] = index.casts %arg0 : i64 to index - // CHECK: [[idx4:%.+]] = index.casts %arg1 : i64 to index - // CHECK: [[alloc3:%.+]] = memref.alloc([[idx3]], [[idx4]]) : memref - // CHECK: quantum.sample {{.*}} in([[alloc3]] : memref) - %samples_dynAll = quantum.sample %obs shape %c1, %c2 : tensor - - func.return -} - -// ----- - -func.func @probs_static(%q0: !quantum.bit, %q1: !quantum.bit) { - %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs - // CHECK: [[alloc:%.+]] = memref.alloc() : memref<4xf64> - // CHECK: quantum.probs {{.*}} in([[alloc]] : memref<4xf64>) - %probs = quantum.probs %obs : tensor<4xf64> - func.return -} - -// ----- - -func.func @probs_dynamic(%q0: !quantum.bit, %q1: !quantum.bit) { - %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs - %c4 = arith.constant 4 : i64 - // CHECK: [[four:%.+]] = arith.constant 4 - // CHECK: [[index:%.+]] = index.casts [[four]] : i64 to index - // CHECK: [[alloc:%.+]] = memref.alloc([[index]]) : memref - // CHECK: quantum.probs {{.*}} in([[alloc]] : memref) - %probs = quantum.probs %obs shape %c4 : tensor - func.return -} - -// ----- - -func.func @state_static(%q0: !quantum.bit, %q1: !quantum.bit) { - %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs - // CHECK: [[alloc:%.+]] = memref.alloc() : memref<4xcomplex> - // CHECK: quantum.state {{.*}} in([[alloc]] : memref<4xcomplex>) - %state = quantum.state %obs : tensor<4xcomplex> - func.return -} - - -// ----- - -func.func @state_dynamic(%r : !quantum.reg) { - %obs = quantum.compbasis qreg %r : !quantum.obs - %c4 = arith.constant 4 : i64 - // CHECK: [[four:%.+]] = arith.constant 4 - // CHECK: [[index:%.+]] = index.casts [[four]] : i64 to index - // CHECK: [[alloc:%.+]] = memref.alloc([[index]]) : memref> - // CHECK: quantum.state {{.*}} in([[alloc]] : memref>) - %state = quantum.state %obs shape %c4 : tensor> - func.return -} - -// ----- +////////////////// +// Measurements // +////////////////// -// CHECK-LABEL: @set_state -module @set_state { - func.func @foo(%arg0: tensor<2xcomplex>, %q0 : !quantum.bit) { - // CHECK: quantum.set_state(%{{.*}}) %{{.*}} : (memref<2xcomplex>, !quantum.bit) -> !quantum.bit - %0 = quantum.set_state(%arg0) %q0 : (tensor<2xcomplex>, !quantum.bit) -> !quantum.bit - return - } +func.func @counts(% q0 + : !quantum.bit, % q1 + : !quantum.bit, % c + : i64){ + % obs = quantum.compbasis qubits % q0, + % + q1 : !quantum.obs + + // CHECK: [[eigval_alloc:%.+]] = memref.alloc() : memref<4xf64> + // CHECK: [[counts_alloc:%.+]] = memref.alloc() : memref<4xi64> + // CHECK: quantum.counts {{.*}} in([[eigval_alloc]] : memref<4xf64>, [[counts_alloc]] : + // memref<4xi64>) + % static_counts : 2 = quantum.counts % obs : tensor<4xf64>, + tensor<4xi64> + + // CHECK: [[idx1:%.+]] = index.casts %arg2 : i64 to index + // CHECK: [[alloc1:%.+]] = memref.alloc([[idx1]]) : memref + // CHECK: [[idx2:%.+]] = index.casts %arg2 : i64 to index + // CHECK: [[alloc2:%.+]] = memref.alloc([[idx2]]) : memref + // CHECK: quantum.counts {{.*}} in([[alloc1]] : memref, [[alloc2]] : memref) + % dyn_counts : 2 = quantum.counts % obs shape % c : tensor < + ? xf64 >, + tensor < + ? xi64 > + + func.return } + + // ----- + + func.func @sample(% c1 + : i64, % c2 + : i64, % q0 + : !quantum.bit, % q1 + : !quantum.bit, % dyn_shots + : i64){ + % obs = quantum.compbasis qubits % q0, + % + q1 : !quantum.obs + + // CHECK: [[idx1:%.+]] = index.casts %arg0 : i64 to index + // CHECK: [[alloc1:%.+]] = memref.alloc([[idx1]]) : memref + // CHECK: quantum.sample {{.*}} in([[alloc1]] : memref) + % samples_dyn1 = + quantum.sample % obs shape % c1 : tensor < + ? x2xf64 > + + // CHECK: [[idx2:%.+]] = index.casts %arg1 : i64 to index + // CHECK: [[alloc2:%.+]] = memref.alloc([[idx2]]) : memref<42x?xf64> + // CHECK: quantum.sample {{.*}} in([[alloc2]] : memref<42x?xf64>) + % samples_dyn2 = quantum.sample % obs shape % c2 + : tensor < 42x + ? xf64 > + + // CHECK: [[alloc_static:%.+]] = memref.alloc() : memref<10x2xf64> + // CHECK: quantum.sample {{.*}} in([[alloc_static]] : memref<10x2xf64>) + % samples_static = quantum.sample % obs + : tensor<10x2xf64> + + // CHECK: [[idx3:%.+]] = index.casts %arg0 : i64 to index + // CHECK: [[idx4:%.+]] = index.casts %arg1 : i64 to index + // CHECK: [[alloc3:%.+]] = memref.alloc([[idx3]], [[idx4]]) : + // memref + // CHECK: quantum.sample {{.*}} in([[alloc3]] : memref) + % samples_dynAll = quantum.sample % obs shape % c1, + % c2 : tensor < + ? x + ? xf64 > + + func.return } + + // ----- + + func.func @probs_static(% q0 + : !quantum.bit, % q1 + : !quantum.bit){ + % obs = quantum.compbasis qubits % q0, + % + q1 : !quantum.obs + // CHECK: [[alloc:%.+]] = memref.alloc() : memref<4xf64> + // CHECK: quantum.probs {{.*}} in([[alloc]] : memref<4xf64>) + % probs = quantum.probs % obs : tensor<4xf64> func.return + } + + // ----- + + func.func @probs_dynamic(% q0 + : !quantum.bit, % q1 + : !quantum.bit){ + % obs = quantum.compbasis qubits % q0, + % q1 : !quantum.obs % + c4 = arith.constant 4 : i64 + // CHECK: [[four:%.+]] = arith.constant 4 + // CHECK: [[index:%.+]] = index.casts [[four]] : i64 to index + // CHECK: [[alloc:%.+]] = memref.alloc([[index]]) : memref + // CHECK: quantum.probs {{.*}} in([[alloc]] : memref) + % probs = quantum.probs % obs shape % c4 : tensor < + ? xf64 > func.return } + + // ----- + + func.func @state_static(% q0 + : !quantum.bit, % q1 + : !quantum.bit){ + % obs = quantum.compbasis qubits % q0, + % + q1 : !quantum.obs + // CHECK: [[alloc:%.+]] = memref.alloc() : + // memref<4xcomplex> + // CHECK: quantum.state {{.*}} in([[alloc]] : + // memref<4xcomplex>) + % state = quantum.state % obs : tensor < 4xcomplex < f64 >> + func.return + } + + // ----- + + func.func @state_dynamic(% r + : !quantum.reg){ + % obs = quantum.compbasis qreg % r : !quantum.obs % + c4 = arith.constant 4 : i64 + // CHECK: [[four:%.+]] = arith.constant 4 + // CHECK: [[index:%.+]] = index.casts [[four]] : i64 + // to index + // CHECK: [[alloc:%.+]] = memref.alloc([[index]]) : + // memref> + // CHECK: quantum.state {{.*}} in([[alloc]] : + // memref>) + % state = quantum.state % obs shape % c4 : tensor < + ? xcomplex < f64 >> func.return } + + // ----- + + // CHECK-LABEL: @set_state + module @set_state +{ + func.func @foo(% arg0 : tensor < 2xcomplex < f64 >>, % q0 : !quantum.bit) + { + // CHECK: quantum.set_state(%{{.*}}) %{{.*}} : (memref<2xcomplex>, !quantum.bit) -> + // !quantum.bit + % 0 = quantum.set_state(% arg0) % + q0 : (tensor < 2xcomplex < f64 >>, !quantum.bit)->!quantum.bit return + } } // ----- // CHECK-LABEL: @set_basis_state -module @set_basis_state { - func.func @foo(%arg0: tensor<2xi1>, %q0 : !quantum.bit) { - // CHECK: quantum.set_basis_state(%{{.*}}) %{{.*}} : (memref<2xi1>, !quantum.bit) -> !quantum.bit - %0 = quantum.set_basis_state(%arg0) %q0 : (tensor<2xi1>, !quantum.bit) -> !quantum.bit - return - } +module @set_basis_state +{ + func.func @foo(% arg0 : tensor<2xi1>, % q0 : !quantum.bit) + { + // CHECK: quantum.set_basis_state(%{{.*}}) %{{.*}} : (memref<2xi1>, !quantum.bit) -> + // !quantum.bit + % 0 = + quantum.set_basis_state(% arg0) % q0 : (tensor<2xi1>, !quantum.bit)->!quantum.bit return + } } - From 064ca444401020110f0459f998450f6ae05cb6cd Mon Sep 17 00:00:00 2001 From: paul0403 Date: Tue, 29 Apr 2025 11:08:51 -0400 Subject: [PATCH 37/49] I accidentally ran clang-format on test.mlir --- mlir/test/Quantum/BufferizationTest.mlir | 297 +++++++++-------------- 1 file changed, 119 insertions(+), 178 deletions(-) diff --git a/mlir/test/Quantum/BufferizationTest.mlir b/mlir/test/Quantum/BufferizationTest.mlir index a103540f2c..fb53b96d32 100644 --- a/mlir/test/Quantum/BufferizationTest.mlir +++ b/mlir/test/Quantum/BufferizationTest.mlir @@ -14,48 +14,32 @@ // RUN: quantum-opt --one-shot-bufferize --split-input-file %s | FileCheck %s -func.func @qubit_unitary(% q0 - : !quantum.bit, % matrix - : tensor < 2x2xcomplex < f64 >>){ +func.func @qubit_unitary(%q0: !quantum.bit, %matrix: tensor<2x2xcomplex>) { // CHECK: [[memref:%.+]] = bufferization.to_memref %arg1 : memref<2x2xcomplex> // CHECK: {{%.+}} = quantum.unitary([[memref]] : memref<2x2xcomplex>) %arg0 : !quantum.bit - % out_qubits = quantum.unitary(% matrix - : tensor < 2x2xcomplex < f64 >>) % - q0 : !quantum - .bit + %out_qubits = quantum.unitary(%matrix : tensor<2x2xcomplex>) %q0 : !quantum.bit - func.return + func.return } // ----- -func.func @hermitian(% q0 - : !quantum.bit, % matrix - : tensor < 2x2xcomplex < f64 >>){ +func.func @hermitian(%q0: !quantum.bit, %matrix: tensor<2x2xcomplex>) { // CHECK: [[memref:%.+]] = bufferization.to_memref %arg1 : memref<2x2xcomplex> - // CHECK: {{%.+}} = quantum.hermitian([[memref]] : memref<2x2xcomplex>) %arg0 : - // !quantum.obs - % obs = quantum.hermitian(% matrix - : tensor < 2x2xcomplex < f64 >>) % - q0 : !quantum - .obs - - func.return + // CHECK: {{%.+}} = quantum.hermitian([[memref]] : memref<2x2xcomplex>) %arg0 : !quantum.obs + %obs = quantum.hermitian(%matrix : tensor<2x2xcomplex>) %q0 : !quantum.obs + + func.return } // ----- -func.func @hamiltonian(% obs - : !quantum.obs, % coeffs - : tensor<1xf64>){ +func.func @hamiltonian(%obs: !quantum.obs, %coeffs: tensor<1xf64>){ // CHECK: [[memref:%.+]] = bufferization.to_memref %arg1 : memref<1xf64> // CHECK: {{%.+}} = quantum.hamiltonian([[memref]] : memref<1xf64>) %arg0 : !quantum.obs - % hamil = quantum.hamiltonian(% coeffs - : tensor<1xf64>) % - obs : !quantum - .obs + %hamil = quantum.hamiltonian(%coeffs: tensor<1xf64>) %obs : !quantum.obs - func.return + func.return } // ----- @@ -64,160 +48,117 @@ func.func @hamiltonian(% obs // Measurements // ////////////////// -func.func @counts(% q0 - : !quantum.bit, % q1 - : !quantum.bit, % c - : i64){ - % obs = quantum.compbasis qubits % q0, - % - q1 : !quantum.obs - - // CHECK: [[eigval_alloc:%.+]] = memref.alloc() : memref<4xf64> - // CHECK: [[counts_alloc:%.+]] = memref.alloc() : memref<4xi64> - // CHECK: quantum.counts {{.*}} in([[eigval_alloc]] : memref<4xf64>, [[counts_alloc]] : - // memref<4xi64>) - % static_counts : 2 = quantum.counts % obs : tensor<4xf64>, - tensor<4xi64> - - // CHECK: [[idx1:%.+]] = index.casts %arg2 : i64 to index - // CHECK: [[alloc1:%.+]] = memref.alloc([[idx1]]) : memref - // CHECK: [[idx2:%.+]] = index.casts %arg2 : i64 to index - // CHECK: [[alloc2:%.+]] = memref.alloc([[idx2]]) : memref - // CHECK: quantum.counts {{.*}} in([[alloc1]] : memref, [[alloc2]] : memref) - % dyn_counts : 2 = quantum.counts % obs shape % c : tensor < - ? xf64 >, - tensor < - ? xi64 > - - func.return } - - // ----- - - func.func @sample(% c1 - : i64, % c2 - : i64, % q0 - : !quantum.bit, % q1 - : !quantum.bit, % dyn_shots - : i64){ - % obs = quantum.compbasis qubits % q0, - % - q1 : !quantum.obs - - // CHECK: [[idx1:%.+]] = index.casts %arg0 : i64 to index - // CHECK: [[alloc1:%.+]] = memref.alloc([[idx1]]) : memref - // CHECK: quantum.sample {{.*}} in([[alloc1]] : memref) - % samples_dyn1 = - quantum.sample % obs shape % c1 : tensor < - ? x2xf64 > - - // CHECK: [[idx2:%.+]] = index.casts %arg1 : i64 to index - // CHECK: [[alloc2:%.+]] = memref.alloc([[idx2]]) : memref<42x?xf64> - // CHECK: quantum.sample {{.*}} in([[alloc2]] : memref<42x?xf64>) - % samples_dyn2 = quantum.sample % obs shape % c2 - : tensor < 42x - ? xf64 > - - // CHECK: [[alloc_static:%.+]] = memref.alloc() : memref<10x2xf64> - // CHECK: quantum.sample {{.*}} in([[alloc_static]] : memref<10x2xf64>) - % samples_static = quantum.sample % obs - : tensor<10x2xf64> - - // CHECK: [[idx3:%.+]] = index.casts %arg0 : i64 to index - // CHECK: [[idx4:%.+]] = index.casts %arg1 : i64 to index - // CHECK: [[alloc3:%.+]] = memref.alloc([[idx3]], [[idx4]]) : - // memref - // CHECK: quantum.sample {{.*}} in([[alloc3]] : memref) - % samples_dynAll = quantum.sample % obs shape % c1, - % c2 : tensor < - ? x - ? xf64 > - - func.return } - - // ----- - - func.func @probs_static(% q0 - : !quantum.bit, % q1 - : !quantum.bit){ - % obs = quantum.compbasis qubits % q0, - % - q1 : !quantum.obs - // CHECK: [[alloc:%.+]] = memref.alloc() : memref<4xf64> - // CHECK: quantum.probs {{.*}} in([[alloc]] : memref<4xf64>) - % probs = quantum.probs % obs : tensor<4xf64> func.return - } - - // ----- - - func.func @probs_dynamic(% q0 - : !quantum.bit, % q1 - : !quantum.bit){ - % obs = quantum.compbasis qubits % q0, - % q1 : !quantum.obs % - c4 = arith.constant 4 : i64 - // CHECK: [[four:%.+]] = arith.constant 4 - // CHECK: [[index:%.+]] = index.casts [[four]] : i64 to index - // CHECK: [[alloc:%.+]] = memref.alloc([[index]]) : memref - // CHECK: quantum.probs {{.*}} in([[alloc]] : memref) - % probs = quantum.probs % obs shape % c4 : tensor < - ? xf64 > func.return } - - // ----- - - func.func @state_static(% q0 - : !quantum.bit, % q1 - : !quantum.bit){ - % obs = quantum.compbasis qubits % q0, - % - q1 : !quantum.obs - // CHECK: [[alloc:%.+]] = memref.alloc() : - // memref<4xcomplex> - // CHECK: quantum.state {{.*}} in([[alloc]] : - // memref<4xcomplex>) - % state = quantum.state % obs : tensor < 4xcomplex < f64 >> - func.return - } - - // ----- - - func.func @state_dynamic(% r - : !quantum.reg){ - % obs = quantum.compbasis qreg % r : !quantum.obs % - c4 = arith.constant 4 : i64 - // CHECK: [[four:%.+]] = arith.constant 4 - // CHECK: [[index:%.+]] = index.casts [[four]] : i64 - // to index - // CHECK: [[alloc:%.+]] = memref.alloc([[index]]) : - // memref> - // CHECK: quantum.state {{.*}} in([[alloc]] : - // memref>) - % state = quantum.state % obs shape % c4 : tensor < - ? xcomplex < f64 >> func.return } - - // ----- - - // CHECK-LABEL: @set_state - module @set_state -{ - func.func @foo(% arg0 : tensor < 2xcomplex < f64 >>, % q0 : !quantum.bit) - { - // CHECK: quantum.set_state(%{{.*}}) %{{.*}} : (memref<2xcomplex>, !quantum.bit) -> - // !quantum.bit - % 0 = quantum.set_state(% arg0) % - q0 : (tensor < 2xcomplex < f64 >>, !quantum.bit)->!quantum.bit return - } +func.func @counts(%q0: !quantum.bit, %q1: !quantum.bit, %c : i64) { + %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs + + // CHECK: [[eigval_alloc:%.+]] = memref.alloc() : memref<4xf64> + // CHECK: [[counts_alloc:%.+]] = memref.alloc() : memref<4xi64> + // CHECK: quantum.counts {{.*}} in([[eigval_alloc]] : memref<4xf64>, [[counts_alloc]] : memref<4xi64>) + %static_counts:2 = quantum.counts %obs : tensor<4xf64>, tensor<4xi64> + + // CHECK: [[idx1:%.+]] = index.casts %arg2 : i64 to index + // CHECK: [[alloc1:%.+]] = memref.alloc([[idx1]]) : memref + // CHECK: [[idx2:%.+]] = index.casts %arg2 : i64 to index + // CHECK: [[alloc2:%.+]] = memref.alloc([[idx2]]) : memref + // CHECK: quantum.counts {{.*}} in([[alloc1]] : memref, [[alloc2]] : memref) + %dyn_counts:2 = quantum.counts %obs shape %c : tensor, tensor + + func.return +} + +// ----- + +func.func @sample(%c1 : i64, %c2 : i64, %q0: !quantum.bit, %q1: !quantum.bit, %dyn_shots: i64) { + %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs + + // CHECK: [[idx1:%.+]] = index.casts %arg0 : i64 to index + // CHECK: [[alloc1:%.+]] = memref.alloc([[idx1]]) : memref + // CHECK: quantum.sample {{.*}} in([[alloc1]] : memref) + %samples_dyn1 = quantum.sample %obs shape %c1: tensor + + // CHECK: [[idx2:%.+]] = index.casts %arg1 : i64 to index + // CHECK: [[alloc2:%.+]] = memref.alloc([[idx2]]) : memref<42x?xf64> + // CHECK: quantum.sample {{.*}} in([[alloc2]] : memref<42x?xf64>) + %samples_dyn2 = quantum.sample %obs shape %c2 : tensor<42x?xf64> + + // CHECK: [[alloc_static:%.+]] = memref.alloc() : memref<10x2xf64> + // CHECK: quantum.sample {{.*}} in([[alloc_static]] : memref<10x2xf64>) + %samples_static = quantum.sample %obs : tensor<10x2xf64> + + // CHECK: [[idx3:%.+]] = index.casts %arg0 : i64 to index + // CHECK: [[idx4:%.+]] = index.casts %arg1 : i64 to index + // CHECK: [[alloc3:%.+]] = memref.alloc([[idx3]], [[idx4]]) : memref + // CHECK: quantum.sample {{.*}} in([[alloc3]] : memref) + %samples_dynAll = quantum.sample %obs shape %c1, %c2 : tensor + + func.return +} + +// ----- + +func.func @probs_static(%q0: !quantum.bit, %q1: !quantum.bit) { + %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs + // CHECK: [[alloc:%.+]] = memref.alloc() : memref<4xf64> + // CHECK: quantum.probs {{.*}} in([[alloc]] : memref<4xf64>) + %probs = quantum.probs %obs : tensor<4xf64> + func.return +} + +// ----- + +func.func @probs_dynamic(%q0: !quantum.bit, %q1: !quantum.bit) { + %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs + %c4 = arith.constant 4 : i64 + // CHECK: [[four:%.+]] = arith.constant 4 + // CHECK: [[index:%.+]] = index.casts [[four]] : i64 to index + // CHECK: [[alloc:%.+]] = memref.alloc([[index]]) : memref + // CHECK: quantum.probs {{.*}} in([[alloc]] : memref) + %probs = quantum.probs %obs shape %c4 : tensor + func.return +} + +// ----- + +func.func @state_static(%q0: !quantum.bit, %q1: !quantum.bit) { + %obs = quantum.compbasis qubits %q0, %q1 : !quantum.obs + // CHECK: [[alloc:%.+]] = memref.alloc() : memref<4xcomplex> + // CHECK: quantum.state {{.*}} in([[alloc]] : memref<4xcomplex>) + %state = quantum.state %obs : tensor<4xcomplex> + func.return +} + + +// ----- + +func.func @state_dynamic(%r : !quantum.reg) { + %obs = quantum.compbasis qreg %r : !quantum.obs + %c4 = arith.constant 4 : i64 + // CHECK: [[four:%.+]] = arith.constant 4 + // CHECK: [[index:%.+]] = index.casts [[four]] : i64 to index + // CHECK: [[alloc:%.+]] = memref.alloc([[index]]) : memref> + // CHECK: quantum.state {{.*}} in([[alloc]] : memref>) + %state = quantum.state %obs shape %c4 : tensor> + func.return +} + +// ----- + +// CHECK-LABEL: @set_state +module @set_state { + func.func @foo(%arg0: tensor<2xcomplex>, %q0 : !quantum.bit) { + // CHECK: quantum.set_state(%{{.*}}) %{{.*}} : (memref<2xcomplex>, !quantum.bit) -> !quantum.bit + %0 = quantum.set_state(%arg0) %q0 : (tensor<2xcomplex>, !quantum.bit) -> !quantum.bit + return + } } // ----- // CHECK-LABEL: @set_basis_state -module @set_basis_state -{ - func.func @foo(% arg0 : tensor<2xi1>, % q0 : !quantum.bit) - { - // CHECK: quantum.set_basis_state(%{{.*}}) %{{.*}} : (memref<2xi1>, !quantum.bit) -> - // !quantum.bit - % 0 = - quantum.set_basis_state(% arg0) % q0 : (tensor<2xi1>, !quantum.bit)->!quantum.bit return - } +module @set_basis_state { + func.func @foo(%arg0: tensor<2xi1>, %q0 : !quantum.bit) { + // CHECK: quantum.set_basis_state(%{{.*}}) %{{.*}} : (memref<2xi1>, !quantum.bit) -> !quantum.bit + %0 = quantum.set_basis_state(%arg0) %q0 : (tensor<2xi1>, !quantum.bit) -> !quantum.bit + return + } } From ebf6b107597b98aa739a36a998c58b232fa73eca Mon Sep 17 00:00:00 2001 From: paul0403 Date: Tue, 29 Apr 2025 11:15:45 -0400 Subject: [PATCH 38/49] format --- frontend/catalyst/pipelines.py | 1 - mlir/lib/Driver/CompilerDriver.cpp | 4 +--- mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp | 3 +-- mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/frontend/catalyst/pipelines.py b/frontend/catalyst/pipelines.py index c30cfc8249..49ece83c56 100644 --- a/frontend/catalyst/pipelines.py +++ b/frontend/catalyst/pipelines.py @@ -230,7 +230,6 @@ def get_bufferization_stage(_options: CompileOptions) -> List[str]: "catalyst-bufferize", # Must be run before -- func.func(linalg-bufferize) "func.func(linalg-bufferize)", "func.func(tensor-bufferize)", - #"quantum-bufferize", "one-shot-bufferize{dialect-filter=quantum}", "func-bufferize", "func.func(finalizing-bufferize)", diff --git a/mlir/lib/Driver/CompilerDriver.cpp b/mlir/lib/Driver/CompilerDriver.cpp index c9546bed07..2875ad79a7 100644 --- a/mlir/lib/Driver/CompilerDriver.cpp +++ b/mlir/lib/Driver/CompilerDriver.cpp @@ -734,11 +734,9 @@ LogicalResult QuantumDriverMain(const CompilerOptions &options, CompilerOutput & if (runTranslate && (inType == InputType::MLIR)) { TimingScope translateTiming = timing.nest("Translate"); - // TODO: Change to true for release. - //bool disableVerification = false; llvmModule = timer::timer(translateModuleToLLVMIR, "translateModuleToLLVMIR", - /* add_endl */ false, *mlirModule, llvmContext, "LLVMDialectModule");//, disableVerification); + /* add_endl */ false, *mlirModule, llvmContext, "LLVMDialectModule"); if (!llvmModule) { CO_MSG(options, Verbosity::Urgent, "Failed to translate LLVM module\n"); return failure(); diff --git a/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp b/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp index c242689d64..03bd8bff81 100644 --- a/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp +++ b/mlir/lib/QEC/Transforms/CommuteCliffordPastPPM.cpp @@ -12,12 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. - #define DEBUG_TYPE "merge_ppr_ppm" +#include "mlir/Analysis/SliceAnalysis.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" -#include "mlir/Analysis/SliceAnalysis.h" //#include "mlir/Analysis/TopologicalSortUtils.h" // enable when updating llvm #include "mlir/Transforms/TopologicalSortUtils.h" diff --git a/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp b/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp index f389b0d14c..ebfa5aac84 100644 --- a/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp +++ b/mlir/lib/QEC/Transforms/CommuteCliffordTPPR.cpp @@ -15,7 +15,7 @@ #define DEBUG_TYPE "commute_ppr" #include "llvm/Support/Debug.h" -//#include "mlir/Analysis/TopologicalSortUtils.h" +//#include "mlir/Analysis/TopologicalSortUtils.h" // enable when updating llvm #include "mlir/Transforms/TopologicalSortUtils.h" #include "QEC/IR/QECDialect.h" From 7524f35a63dcc85ba00aaa31c0ce45d5586d9192 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Tue, 29 Apr 2025 14:06:33 -0400 Subject: [PATCH 39/49] remove old quantum bufferization pass --- mlir/include/Quantum/Transforms/Passes.td | 11 - .../Catalyst/Transforms/RegisterAllPasses.cpp | 1 - mlir/lib/Driver/Pipelines.cpp | 1 - .../Transforms/BufferizationPatterns.cpp | 259 ------------------ .../Quantum/Transforms/quantum_bufferize.cpp | 63 ----- 5 files changed, 335 deletions(-) delete mode 100644 mlir/lib/Quantum/Transforms/BufferizationPatterns.cpp delete mode 100644 mlir/lib/Quantum/Transforms/quantum_bufferize.cpp diff --git a/mlir/include/Quantum/Transforms/Passes.td b/mlir/include/Quantum/Transforms/Passes.td index 496c36906f..c120f5a501 100644 --- a/mlir/include/Quantum/Transforms/Passes.td +++ b/mlir/include/Quantum/Transforms/Passes.td @@ -17,17 +17,6 @@ include "mlir/Pass/PassBase.td" -def QuantumBufferizationPass : Pass<"quantum-bufferize"> { - let summary = "Bufferize tensors in quantum operations."; - - let dependentDialects = [ - "bufferization::BufferizationDialect", - "memref::MemRefDialect" - ]; - - let constructor = "catalyst::createQuantumBufferizationPass()"; -} - def QuantumConversionPass : Pass<"convert-quantum-to-llvm"> { let summary = "Perform a dialect conversion from Quantum to LLVM (QIR)."; diff --git a/mlir/lib/Catalyst/Transforms/RegisterAllPasses.cpp b/mlir/lib/Catalyst/Transforms/RegisterAllPasses.cpp index 459e887020..cc1379a6d1 100644 --- a/mlir/lib/Catalyst/Transforms/RegisterAllPasses.cpp +++ b/mlir/lib/Catalyst/Transforms/RegisterAllPasses.cpp @@ -50,7 +50,6 @@ void catalyst::registerAllCatalystPasses() mlir::registerPass(catalyst::createMemrefToLLVMWithTBAAPass); mlir::registerPass(catalyst::createMitigationLoweringPass); mlir::registerPass(catalyst::createQnodeToAsyncLoweringPass); - mlir::registerPass(catalyst::createQuantumBufferizationPass); mlir::registerPass(catalyst::createQuantumConversionPass); mlir::registerPass(catalyst::createRegisterInactiveCallbackPass); mlir::registerPass(catalyst::createRemoveChainedSelfInversePass); diff --git a/mlir/lib/Driver/Pipelines.cpp b/mlir/lib/Driver/Pipelines.cpp index d1e2dc3eb9..957a3f2af4 100644 --- a/mlir/lib/Driver/Pipelines.cpp +++ b/mlir/lib/Driver/Pipelines.cpp @@ -79,7 +79,6 @@ void createBufferizationPipeline(OpPassManager &pm) pm.addPass(catalyst::createCatalystBufferizationPass()); pm.addNestedPass(mlir::createLinalgBufferizePass()); pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); - pm.addPass(catalyst::createQuantumBufferizationPass()); pm.addPass(mlir::func::createFuncBufferizePass()); pm.addNestedPass(mlir::bufferization::createFinalizingBufferizePass()); pm.addPass(mlir::createCanonicalizerPass()); diff --git a/mlir/lib/Quantum/Transforms/BufferizationPatterns.cpp b/mlir/lib/Quantum/Transforms/BufferizationPatterns.cpp deleted file mode 100644 index b48493ef1e..0000000000 --- a/mlir/lib/Quantum/Transforms/BufferizationPatterns.cpp +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2022-2023 Xanadu Quantum Technologies Inc. - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "mlir/Dialect/Bufferization/IR/Bufferization.h" -#include "mlir/Dialect/Func/IR/FuncOps.h" -#include "mlir/Dialect/Index/IR/IndexDialect.h" -#include "mlir/Dialect/Index/IR/IndexOps.h" -#include "mlir/Dialect/MemRef/IR/MemRef.h" -#include "mlir/IR/BuiltinTypes.h" -#include "mlir/Transforms/DialectConversion.h" - -#include "Quantum/IR/QuantumOps.h" -#include "Quantum/Transforms/Patterns.h" - -using namespace mlir; -using namespace catalyst::quantum; - -namespace { - -struct BufferizeQubitUnitaryOp : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite(QubitUnitaryOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override - { - rewriter.replaceOpWithNewOp( - op, op.getOutQubits().getTypes(), op.getOutCtrlQubits().getTypes(), adaptor.getMatrix(), - adaptor.getInQubits(), adaptor.getAdjointAttr(), adaptor.getInCtrlQubits(), - adaptor.getInCtrlValues()); - return success(); - } -}; - -struct BufferizeHermitianOp : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite(HermitianOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override - { - rewriter.replaceOpWithNewOp(op, op.getType(), adaptor.getMatrix(), - adaptor.getQubits()); - return success(); - } -}; - -struct BufferizeHamiltonianOp : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite(HamiltonianOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override - { - rewriter.replaceOpWithNewOp(op, op.getType(), adaptor.getCoeffs(), - adaptor.getTerms()); - return success(); - } -}; - -struct BufferizeSampleOp : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite(SampleOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override - { - Type tensorType = op.getType(0); - MemRefType resultType = cast(getTypeConverter()->convertType(tensorType)); - Location loc = op.getLoc(); - - SmallVector allocSizes; - for (Value dynShapeDimension : op.getDynamicShape()) { - auto indexCastOp = - rewriter.create(loc, rewriter.getIndexType(), dynShapeDimension); - allocSizes.push_back(indexCastOp); - } - - Value allocVal = rewriter.replaceOpWithNewOp(op, resultType, allocSizes); - auto allocedSampleOp = rewriter.create( - loc, TypeRange{}, ValueRange{adaptor.getObs(), allocVal}, op->getAttrs()); - allocedSampleOp->setAttr("operandSegmentSizes", rewriter.getDenseI32ArrayAttr({1, 0, 1})); - return success(); - } -}; - -struct BufferizeStateOp : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite(StateOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override - { - Type tensorType = op.getType(0); - MemRefType resultType = cast(getTypeConverter()->convertType(tensorType)); - Location loc = op.getLoc(); - - Value buffer; - auto shape = cast(tensorType).getShape(); - if (shape[0] == ShapedType::kDynamic) { - auto indexCastOp = - rewriter.create(loc, rewriter.getIndexType(), op.getDynamicShape()); - buffer = rewriter.replaceOpWithNewOp(op, resultType, - ValueRange{indexCastOp}); - } - else { - buffer = rewriter.replaceOpWithNewOp(op, resultType); - } - - auto allocedStateOp = - rewriter.create(loc, TypeRange{}, ValueRange{adaptor.getObs(), buffer}); - allocedStateOp->setAttr("operandSegmentSizes", rewriter.getDenseI32ArrayAttr({1, 0, 1})); - return success(); - } -}; - -struct BufferizeProbsOp : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite(ProbsOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override - { - Type tensorType = op.getType(0); - MemRefType resultType = cast(getTypeConverter()->convertType(tensorType)); - Location loc = op.getLoc(); - - Value buffer; - auto shape = cast(tensorType).getShape(); - if (shape[0] == ShapedType::kDynamic) { - auto indexCastOp = - rewriter.create(loc, rewriter.getIndexType(), op.getDynamicShape()); - buffer = rewriter.replaceOpWithNewOp(op, resultType, - ValueRange{indexCastOp}); - } - else { - buffer = rewriter.replaceOpWithNewOp(op, resultType); - } - - auto allocedProbsOp = - rewriter.create(loc, TypeRange{}, ValueRange{adaptor.getObs(), buffer}); - allocedProbsOp->setAttr("operandSegmentSizes", rewriter.getDenseI32ArrayAttr({1, 0, 1})); - return success(); - } -}; - -struct BufferizeCountsOp : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite(CountsOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override - { - Location loc = op.getLoc(); - SmallVector buffers; - for (size_t i : {0, 1}) { - Type tensorType = op.getType(i); - MemRefType resultType = cast(getTypeConverter()->convertType(tensorType)); - auto shape = cast(tensorType).getShape(); - - Value allocVal; - if (shape[0] == ShapedType::kDynamic) { - auto indexCastOp = rewriter.create(loc, rewriter.getIndexType(), - op.getDynamicShape()); - allocVal = - rewriter.create(loc, resultType, ValueRange{indexCastOp}); - } - else { - allocVal = rewriter.create(loc, resultType); - } - buffers.push_back(allocVal); - } - rewriter.replaceOp(op, buffers); - - rewriter.create(loc, nullptr, nullptr, adaptor.getObs(), nullptr, buffers[0], - buffers[1]); - - return success(); - } -}; - -struct BufferizeSetStateOp : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite(SetStateOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override - { - Type tensorType = op.getInState().getType(); - MemRefType memrefType = cast(getTypeConverter()->convertType(tensorType)); - auto toMemrefOp = - rewriter.create(op->getLoc(), memrefType, op.getInState()); - auto memref = toMemrefOp.getResult(); - rewriter.replaceOpWithNewOp(op, op.getOutQubits().getTypes(), memref, - adaptor.getInQubits()); - return success(); - } -}; - -struct BufferizeSetBasisStateOp : public OpConversionPattern { - using OpConversionPattern::OpConversionPattern; - - LogicalResult matchAndRewrite(SetBasisStateOp op, OpAdaptor adaptor, - ConversionPatternRewriter &rewriter) const override - { - Type tensorType = op.getBasisState().getType(); - MemRefType memrefType = cast(getTypeConverter()->convertType(tensorType)); - auto toMemrefOp = rewriter.create(op->getLoc(), memrefType, - op.getBasisState()); - auto memref = toMemrefOp.getResult(); - rewriter.replaceOpWithNewOp(op, op.getOutQubits().getTypes(), memref, - adaptor.getInQubits()); - return success(); - } -}; - -} // namespace - -namespace catalyst { -namespace quantum { - -void populateBufferizationLegality(TypeConverter &typeConverter, ConversionTarget &target) -{ - // Default to operations being legal with the exception of the ones below. - target.markUnknownOpDynamicallyLegal([](Operation *) { return true; }); - // Quantum ops which return arrays need to be marked illegal when the type is a tensor. - target.addDynamicallyLegalOp( - [&](QubitUnitaryOp op) { return typeConverter.isLegal(op.getMatrix().getType()); }); - target.addDynamicallyLegalOp( - [&](HermitianOp op) { return typeConverter.isLegal(op.getMatrix().getType()); }); - target.addDynamicallyLegalOp( - [&](HamiltonianOp op) { return typeConverter.isLegal(op.getCoeffs().getType()); }); - target.addDynamicallyLegalOp([&](SampleOp op) { return op.isBufferized(); }); - target.addDynamicallyLegalOp([&](StateOp op) { return op.isBufferized(); }); - target.addDynamicallyLegalOp([&](ProbsOp op) { return op.isBufferized(); }); - target.addDynamicallyLegalOp([&](CountsOp op) { return op.isBufferized(); }); - target.addDynamicallyLegalOp([&](SetStateOp op) { return op.isBufferized(); }); - target.addDynamicallyLegalOp( - [&](SetBasisStateOp op) { return op.isBufferized(); }); -} - -void populateBufferizationPatterns(TypeConverter &typeConverter, RewritePatternSet &patterns) -{ - patterns.add(typeConverter, patterns.getContext()); - patterns.add(typeConverter, patterns.getContext()); - patterns.add(typeConverter, patterns.getContext()); - patterns.add(typeConverter, patterns.getContext()); - patterns.add(typeConverter, patterns.getContext()); - patterns.add(typeConverter, patterns.getContext()); - patterns.add(typeConverter, patterns.getContext()); - patterns.add(typeConverter, patterns.getContext()); - patterns.add(typeConverter, patterns.getContext()); -} - -} // namespace quantum -} // namespace catalyst diff --git a/mlir/lib/Quantum/Transforms/quantum_bufferize.cpp b/mlir/lib/Quantum/Transforms/quantum_bufferize.cpp deleted file mode 100644 index 901f79da6f..0000000000 --- a/mlir/lib/Quantum/Transforms/quantum_bufferize.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2022-2023 Xanadu Quantum Technologies Inc. - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 - -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "mlir/Dialect/Bufferization/IR/Bufferization.h" -#include "mlir/Dialect/Bufferization/Transforms/Bufferize.h" -#include "mlir/Dialect/MemRef/IR/MemRef.h" -#include "mlir/IR/BuiltinOps.h" -#include "mlir/Pass/Pass.h" -#include "mlir/Transforms/DialectConversion.h" - -#include "Quantum/IR/QuantumOps.h" -#include "Quantum/Transforms/Passes.h" -#include "Quantum/Transforms/Patterns.h" - -using namespace mlir; -using namespace catalyst::quantum; - -namespace catalyst { -namespace quantum { - -#define GEN_PASS_DEF_QUANTUMBUFFERIZATIONPASS -#include "Quantum/Transforms/Passes.h.inc" - -struct QuantumBufferizationPass : impl::QuantumBufferizationPassBase { - using QuantumBufferizationPassBase::QuantumBufferizationPassBase; - - void runOnOperation() final - { - MLIRContext *context = &getContext(); - bufferization::BufferizeTypeConverter typeConverter; - - RewritePatternSet patterns(context); - populateBufferizationPatterns(typeConverter, patterns); - - ConversionTarget target(*context); - bufferization::populateBufferizeMaterializationLegality(target); - populateBufferizationLegality(typeConverter, target); - - if (failed(applyPartialConversion(getOperation(), target, std::move(patterns)))) { - signalPassFailure(); - } - } -}; - -} // namespace quantum - -std::unique_ptr createQuantumBufferizationPass() -{ - return std::make_unique(); -} - -} // namespace catalyst From 89bdc03b7faacb3a20b0eb5442be70c75d28b406 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Tue, 29 Apr 2025 14:38:46 -0400 Subject: [PATCH 40/49] add one shot quantum bufferize to cpp pipeline --- mlir/lib/Driver/Pipelines.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mlir/lib/Driver/Pipelines.cpp b/mlir/lib/Driver/Pipelines.cpp index 957a3f2af4..46a3079c69 100644 --- a/mlir/lib/Driver/Pipelines.cpp +++ b/mlir/lib/Driver/Pipelines.cpp @@ -16,6 +16,7 @@ #include "Catalyst/Transforms/Passes.h" #include "Gradient/Transforms/Passes.h" #include "Mitigation/Transforms/Passes.h" +#include "Quantum/IR/QuantumDialect.h" #include "Quantum/Transforms/Passes.h" #include "mhlo/transforms/passes.h" #include "mlir/InitAllDialects.h" @@ -79,6 +80,9 @@ void createBufferizationPipeline(OpPassManager &pm) pm.addPass(catalyst::createCatalystBufferizationPass()); pm.addNestedPass(mlir::createLinalgBufferizePass()); pm.addNestedPass(mlir::tensor::createTensorBufferizePass()); + mlir::bufferization::OneShotBufferizationOptions quantum_buffer_options; + quantum_buffer_options.opFilter.allowDialect(); + pm.addPass(mlir::bufferization::createOneShotBufferizePass(quantum_buffer_options)); pm.addPass(mlir::func::createFuncBufferizePass()); pm.addNestedPass(mlir::bufferization::createFinalizingBufferizePass()); pm.addPass(mlir::createCanonicalizerPass()); From d45d859cd05ec0d44e8bfd874b3e6247b18632e9 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Tue, 29 Apr 2025 16:00:05 -0400 Subject: [PATCH 41/49] changelog --- doc/releases/changelog-dev.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index d5c0998bac..d87fa243f7 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -71,6 +71,9 @@ * The utility function `EnsureFunctionDeclaration` is refactored into the `Utils` of the `Catalyst` dialect, instead of being duplicated in each individual dialect. [(#1683)](https://github.com/PennyLaneAI/catalyst/pull/1683) +* The bufferization of custom catalyst dialects has been migrated to the new one-shot bufferization interface in mlir. The new mlir bufferization interface is required by jax 0.4.29 or higher. + [(#1686)](https://github.com/PennyLaneAI/catalyst/pull/1686) +

Documentation 📝

Contributors ✍️

@@ -80,6 +83,7 @@ This release contains contributions from (in alphabetical order): Joey Carter, Sengthai Heng, David Ittah, +Tzung-Han Juang, Christina Lee, Erick Ochoa Lopez, Paul Haochen Wang. From 5e131514c735e51ae31693b4a286198bb6408e48 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Wed, 30 Apr 2025 08:47:44 -0400 Subject: [PATCH 42/49] remove BufferizationPatterns.cpp from cmakelists --- mlir/lib/Quantum/Transforms/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/mlir/lib/Quantum/Transforms/CMakeLists.txt b/mlir/lib/Quantum/Transforms/CMakeLists.txt index ed0e22d885..529325372f 100644 --- a/mlir/lib/Quantum/Transforms/CMakeLists.txt +++ b/mlir/lib/Quantum/Transforms/CMakeLists.txt @@ -2,7 +2,6 @@ set(LIBRARY_NAME quantum-transforms) file(GLOB SRC BufferizableOpInterfaceImpl.cpp - BufferizationPatterns.cpp quantum_bufferize.cpp ConversionPatterns.cpp quantum_to_llvm.cpp From ddde95551394431799389e6b3c22e0ce7bd101a8 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Thu, 1 May 2025 11:10:40 -0400 Subject: [PATCH 43/49] remove extra comments --- mlir/include/Quantum/IR/QuantumOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/include/Quantum/IR/QuantumOps.td b/mlir/include/Quantum/IR/QuantumOps.td index 008222f9ee..23d2345bfc 100644 --- a/mlir/include/Quantum/IR/QuantumOps.td +++ b/mlir/include/Quantum/IR/QuantumOps.td @@ -63,7 +63,7 @@ def NamedObservableAttr : EnumAttr traits = []> : Op; -def InitializeOp : Quantum_Op<"init"> { //, [NoMemoryEffect]> { +def InitializeOp : Quantum_Op<"init"> { let summary = "Initialize the quantum runtime."; let assemblyFormat = [{ @@ -71,7 +71,7 @@ def InitializeOp : Quantum_Op<"init"> { //, [NoMemoryEffect]> { }]; } -def FinalizeOp : Quantum_Op<"finalize"> { //, [NoMemoryEffect]> { +def FinalizeOp : Quantum_Op<"finalize"> { let summary = "Teardown the quantum runtime."; let assemblyFormat = [{ From 6ddcb807908d4bbda37e0a696ef59a5994777be2 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Thu, 1 May 2025 11:26:05 -0400 Subject: [PATCH 44/49] add Tzunghan's origin PR to changelog --- doc/releases/changelog-dev.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index 8bc9c2fdd2..061a4ee833 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -81,6 +81,7 @@ [(#1683)](https://github.com/PennyLaneAI/catalyst/pull/1683) * The bufferization of custom catalyst dialects has been migrated to the new one-shot bufferization interface in mlir. The new mlir bufferization interface is required by jax 0.4.29 or higher. + [(#1027)](https://github.com/PennyLaneAI/catalyst/pull/1027) [(#1686)](https://github.com/PennyLaneAI/catalyst/pull/1686) * Improved the definition of `YieldOp` in the quantum dialect by removing `AnyTypeOf` From 78d1b4c8dbe54c4d092ca9af7449941bc47bf88e Mon Sep 17 00:00:00 2001 From: Paul <79805239+paul0403@users.noreply.github.com> Date: Thu, 1 May 2025 14:49:05 -0400 Subject: [PATCH 45/49] Update mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp Co-authored-by: David Ittah --- .../lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index f0c3b1f9ad..9e8456aa82 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -25,6 +25,13 @@ using namespace mlir; using namespace mlir::bufferization; using namespace catalyst::quantum; +/** + * Implementation of the BufferizableOpInterface for use with one-shot bufferization. + * For more information on the interface, refer to the documentation below: + * - https://mlir.llvm.org/docs/Bufferization/#extending-one-shot-bufferize + * - https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td#L14 + */ + namespace { // Bufferization of quantum.unitary. From 6c9e70e92a6aa8ae9c8f57f6c13481fbf2291218 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Thu, 1 May 2025 14:55:33 -0400 Subject: [PATCH 46/49] format --- mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index 9e8456aa82..894f62eda3 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -28,8 +28,8 @@ using namespace catalyst::quantum; /** * Implementation of the BufferizableOpInterface for use with one-shot bufferization. * For more information on the interface, refer to the documentation below: - * - https://mlir.llvm.org/docs/Bufferization/#extending-one-shot-bufferize - * - https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td#L14 + * https://mlir.llvm.org/docs/Bufferization/#extending-one-shot-bufferize + * https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td#L14 */ namespace { From 61544097002ca75690ef54ba9dd251faaf82b051 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Thu, 1 May 2025 15:37:39 -0400 Subject: [PATCH 47/49] Turn on bufferizesToAllocation for sample, counts, probs and state. These involve replacing tensor results with new memref allocations. --- .../Quantum/Transforms/BufferizableOpInterfaceImpl.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp index 894f62eda3..1460236cca 100644 --- a/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp +++ b/mlir/lib/Quantum/Transforms/BufferizableOpInterfaceImpl.cpp @@ -178,6 +178,8 @@ struct SampleOpInterface return false; } + bool bufferizesToAllocation(Operation *op, Value value) const { return true; } + bufferization::AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand, const bufferization::AnalysisState &state) const @@ -226,6 +228,8 @@ struct CountsOpInterface return false; } + bool bufferizesToAllocation(Operation *op, Value value) const { return true; } + bufferization::AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand, const bufferization::AnalysisState &state) const @@ -284,6 +288,8 @@ struct ProbsOpInterface return false; } + bool bufferizesToAllocation(Operation *op, Value value) const { return true; } + bufferization::AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand, const bufferization::AnalysisState &state) const @@ -335,6 +341,8 @@ struct StateOpInterface return false; } + bool bufferizesToAllocation(Operation *op, Value value) const { return true; } + bufferization::AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand, const bufferization::AnalysisState &state) const From cdea054289884b4cb19ed81d3a0cbcb800822bdc Mon Sep 17 00:00:00 2001 From: paul0403 Date: Thu, 1 May 2025 15:51:56 -0400 Subject: [PATCH 48/49] changelog line too long --- doc/releases/changelog-dev.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index c4c16236cf..1e07e62cca 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -110,7 +110,9 @@ * Improved the definition of `YieldOp` in the quantum dialect by removing `AnyTypeOf` [(#1696)](https://github.com/PennyLaneAI/catalyst/pull/1696) -* The bufferization of custom catalyst dialects has been migrated to the new one-shot bufferization interface in mlir. The new mlir bufferization interface is required by jax 0.4.29 or higher. +* The bufferization of custom catalyst dialects has been migrated to the new one-shot + bufferization interface in mlir. + The new mlir bufferization interface is required by jax 0.4.29 or higher. [(#1027)](https://github.com/PennyLaneAI/catalyst/pull/1027) [(#1686)](https://github.com/PennyLaneAI/catalyst/pull/1686) From 3f2fa2db25dca3b697de99d736bf0dccbdc270e4 Mon Sep 17 00:00:00 2001 From: paul0403 Date: Thu, 1 May 2025 16:01:51 -0400 Subject: [PATCH 49/49] remove quantum_bufferize.cpp from cmakelists --- mlir/lib/Quantum/Transforms/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/mlir/lib/Quantum/Transforms/CMakeLists.txt b/mlir/lib/Quantum/Transforms/CMakeLists.txt index 529325372f..3a244ac4d6 100644 --- a/mlir/lib/Quantum/Transforms/CMakeLists.txt +++ b/mlir/lib/Quantum/Transforms/CMakeLists.txt @@ -2,7 +2,6 @@ set(LIBRARY_NAME quantum-transforms) file(GLOB SRC BufferizableOpInterfaceImpl.cpp - quantum_bufferize.cpp ConversionPatterns.cpp quantum_to_llvm.cpp emit_catalyst_pyface.cpp