Skip to content

Commit f5ecab8

Browse files
j2kuncopybara-github
authored andcommitted
split-preprocessing: use new preprocessing dialect infrastructure
This change modifies split-preprocessing to use the new preprocessing dialect for its output, and updates the pipelines to use preprocessing-to-memref. It changes the `split-preprocessing` flag from a numeric batching factor to a boolean enable/disable. It also adds a small amount of fixes to the lattigo lowering (which otherwise supports bufferization and memrefs). Fixes #2960 PiperOrigin-RevId: 938040235
1 parent 347e801 commit f5ecab8

47 files changed

Lines changed: 613 additions & 410 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lib/Dialect/Preprocessing/Conversions/PreprocessingToLattigo/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ cc_library(
1616
"@heir//lib/Dialect/Lattigo/IR:Dialect",
1717
"@heir//lib/Dialect/Preprocessing/Conversions:Util",
1818
"@heir//lib/Dialect/Preprocessing/IR:Dialect",
19+
"@heir//lib/Utils",
1920
"@heir//lib/Utils:ConversionUtils",
2021
"@llvm-project//mlir:AffineDialect",
2122
"@llvm-project//mlir:ArithDialect",

lib/Dialect/Preprocessing/Conversions/PreprocessingToLattigo/PreprocessingToLattigo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "lib/Dialect/Preprocessing/Conversions/Util.h"
99
#include "lib/Dialect/Preprocessing/IR/PreprocessingDialect.h"
1010
#include "lib/Utils/ConversionUtils.h"
11+
#include "lib/Utils/Utils.h"
1112
#include "mlir/include/mlir/Dialect/Affine/IR/AffineOps.h" // from @llvm-project
1213
#include "mlir/include/mlir/Dialect/Arith/IR/Arith.h" // from @llvm-project
1314
#include "mlir/include/mlir/Dialect/Func/IR/FuncOps.h" // from @llvm-project
@@ -31,6 +32,10 @@ struct PreprocessingToLattigo
3132
void runOnOperation() override {
3233
ModuleOp module = getOperation();
3334

35+
if (!containsDialects<PreprocessingDialect>(module)) {
36+
return;
37+
}
38+
3439
PreprocessingStorageLayoutAnalysis analysis(module);
3540
if (!analysis.isValid()) {
3641
signalPassFailure();

lib/Dialect/Preprocessing/Conversions/PreprocessingToMemref/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ cc_library(
1515
"@heir//lib/Analysis/PreprocessingStorageLayoutAnalysis",
1616
"@heir//lib/Dialect/Preprocessing/Conversions:Util",
1717
"@heir//lib/Dialect/Preprocessing/IR:Dialect",
18+
"@heir//lib/Utils",
1819
"@heir//lib/Utils:ConversionUtils",
1920
"@llvm-project//llvm:Support",
2021
"@llvm-project//mlir:AffineAnalysis",

lib/Dialect/Preprocessing/Conversions/PreprocessingToMemref/PreprocessingToMemref.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "lib/Dialect/Preprocessing/IR/PreprocessingOps.h"
1414
#include "lib/Dialect/Preprocessing/IR/PreprocessingTypes.h"
1515
#include "lib/Utils/ConversionUtils.h"
16+
#include "lib/Utils/Utils.h"
1617
#include "llvm/include/llvm/ADT/STLExtras.h" // from @llvm-project
1718
#include "llvm/include/llvm/ADT/SmallVector.h" // from @llvm-project
1819
#include "mlir/include/mlir/Dialect/Affine/Analysis/LoopAnalysis.h" // from @llvm-project
@@ -214,6 +215,10 @@ struct PreprocessingToMemref
214215
void runOnOperation() override {
215216
ModuleOp module = getOperation();
216217

218+
if (!containsDialects<PreprocessingDialect>(module)) {
219+
return;
220+
}
221+
217222
PreprocessingStorageLayoutAnalysis analysis(module);
218223
if (!analysis.isValid()) {
219224
signalPassFailure();

lib/Dialect/Preprocessing/Conversions/PreprocessingToOpenfhe/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ cc_library(
1616
"@heir//lib/Dialect/Openfhe/IR:Dialect",
1717
"@heir//lib/Dialect/Preprocessing/Conversions:Util",
1818
"@heir//lib/Dialect/Preprocessing/IR:Dialect",
19+
"@heir//lib/Utils",
1920
"@heir//lib/Utils:ConversionUtils",
2021
"@llvm-project//mlir:AffineDialect",
2122
"@llvm-project//mlir:ArithDialect",

lib/Dialect/Preprocessing/Conversions/PreprocessingToOpenfhe/PreprocessingToOpenfhe.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "lib/Dialect/Preprocessing/Conversions/Util.h"
99
#include "lib/Dialect/Preprocessing/IR/PreprocessingDialect.h"
1010
#include "lib/Utils/ConversionUtils.h"
11+
#include "lib/Utils/Utils.h"
1112
#include "mlir/include/mlir/Dialect/Affine/IR/AffineOps.h" // from @llvm-project
1213
#include "mlir/include/mlir/Dialect/Arith/IR/Arith.h" // from @llvm-project
1314
#include "mlir/include/mlir/Dialect/Func/IR/FuncOps.h" // from @llvm-project
@@ -31,6 +32,10 @@ struct PreprocessingToOpenfhe
3132
void runOnOperation() override {
3233
ModuleOp module = getOperation();
3334

35+
if (!containsDialects<PreprocessingDialect>(module)) {
36+
return;
37+
}
38+
3439
PreprocessingStorageLayoutAnalysis analysis(module);
3540
if (!analysis.isValid()) {
3641
signalPassFailure();

lib/Dialect/Preprocessing/IR/PreprocessingOps.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Preprocessing_Op<string mnemonic, list<Trait> traits = []> :
1414
let cppNamespace = "::mlir::heir::preprocessing";
1515
}
1616

17-
def Preprocessing_EmptyOp : Preprocessing_Op<"empty"> {
17+
def Preprocessing_EmptyOp : Preprocessing_Op<"empty", [MemoryEffectsOpInterface]> {
1818
let summary = "Allocate an empty preprocessing storage";
1919
let description = [{
2020
This op creates a new `preprocessing.storage` value with an undetermined size.
@@ -23,7 +23,7 @@ def Preprocessing_EmptyOp : Preprocessing_Op<"empty"> {
2323
let assemblyFormat = "attr-dict `:` type($storage)";
2424
}
2525

26-
def Preprocessing_StoreOp : Preprocessing_Op<"store"> {
26+
def Preprocessing_StoreOp : Preprocessing_Op<"store", [MemoryEffectsOpInterface]> {
2727
let summary = "Store a value to preprocessing storage at given indices and site_id";
2828
let description = [{
2929
This op stores a value into a `preprocessing.storage`, while tracking:
@@ -49,7 +49,7 @@ def Preprocessing_StoreOp : Preprocessing_Op<"store"> {
4949
let assemblyFormat = "$value `,` $storage `[` $indices `]` `site` $site_id `<` $element_type `>` attr-dict `:` type($value) `,` type($storage)";
5050
}
5151

52-
def Preprocessing_LoadOp : Preprocessing_Op<"load"> {
52+
def Preprocessing_LoadOp : Preprocessing_Op<"load", [MemoryEffectsOpInterface]> {
5353
let summary = "Load a value from preprocessing storage at given indices and site_id";
5454
let description = [{
5555
This op loads a value from a `preprocessing.storage`, while tracking:

lib/Dialect/Preprocessing/Transforms/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ cc_library(
2323
":pass_inc_gen",
2424
"@heir//lib/Dialect/Preprocessing/IR:Dialect",
2525
"@llvm-project//llvm:Support",
26+
"@llvm-project//mlir:FuncDialect",
2627
"@llvm-project//mlir:IR",
2728
"@llvm-project//mlir:Pass",
2829
"@llvm-project//mlir:Support",

lib/Dialect/Preprocessing/Transforms/ValidatePreprocessing.cpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66

77
#include "lib/Dialect/Preprocessing/IR/PreprocessingOps.h"
88
#include "lib/Dialect/Preprocessing/IR/PreprocessingTypes.h"
9-
#include "llvm/include/llvm/ADT/ArrayRef.h" // from @llvm-project
10-
#include "llvm/include/llvm/ADT/DenseMap.h" // from @llvm-project
11-
#include "llvm/include/llvm/ADT/SmallVector.h" // from @llvm-project
12-
#include "mlir/include/mlir/IR/Diagnostics.h" // from @llvm-project
13-
#include "mlir/include/mlir/IR/Visitors.h" // from @llvm-project
14-
#include "mlir/include/mlir/Support/LLVM.h" // from @llvm-project
9+
#include "llvm/include/llvm/ADT/ArrayRef.h" // from @llvm-project
10+
#include "llvm/include/llvm/ADT/DenseMap.h" // from @llvm-project
11+
#include "llvm/include/llvm/ADT/SmallVector.h" // from @llvm-project
12+
#include "mlir/include/mlir/Dialect/Func/IR/FuncOps.h" // from @llvm-project
13+
#include "mlir/include/mlir/IR/Diagnostics.h" // from @llvm-project
14+
#include "mlir/include/mlir/IR/Visitors.h" // from @llvm-project
15+
#include "mlir/include/mlir/Support/LLVM.h" // from @llvm-project
1516

1617
namespace mlir {
1718
namespace heir {
@@ -25,30 +26,36 @@ struct ValidatePreprocessing
2526
using ValidatePreprocessingBase::ValidatePreprocessingBase;
2627

2728
void runOnOperation() override {
28-
SmallVector<EmptyOp, 2> emptyOps;
29+
Operation* module = getOperation();
30+
31+
bool hasMultipleEmpties = false;
32+
module->walk([&](func::FuncOp funcOp) {
33+
SmallVector<EmptyOp> emptyOps(funcOp.getOps<EmptyOp>());
34+
if (emptyOps.size() > 1) {
35+
for (size_t i = 1; i < emptyOps.size(); ++i) {
36+
auto diag =
37+
emptyOps[i]->emitOpError()
38+
<< "more than one preprocessing.empty allocation in function";
39+
diag.attachNote(emptyOps[0]->getLoc()) << "previous allocation here";
40+
}
41+
hasMultipleEmpties = true;
42+
}
43+
});
44+
if (hasMultipleEmpties) {
45+
signalPassFailure();
46+
}
47+
2948
DenseMap<uint32_t, SmallVector<StoreOp, 2>> storesBySite;
3049
DenseMap<uint32_t, SmallVector<LoadOp, 2>> loadsBySite;
3150

32-
getOperation()->walk([&](Operation* op) {
33-
if (auto emptyOp = dyn_cast<EmptyOp>(op)) {
34-
emptyOps.push_back(emptyOp);
35-
} else if (auto storeOp = dyn_cast<StoreOp>(op)) {
51+
module->walk([&](Operation* op) {
52+
if (auto storeOp = dyn_cast<StoreOp>(op)) {
3653
storesBySite[storeOp.getSiteId()].push_back(storeOp);
3754
} else if (auto loadOp = dyn_cast<LoadOp>(op)) {
3855
loadsBySite[loadOp.getSiteId()].push_back(loadOp);
3956
}
4057
});
4158

42-
if (emptyOps.size() > 1) {
43-
for (size_t i = 1; i < emptyOps.size(); ++i) {
44-
auto diag = emptyOps[i]->emitOpError()
45-
<< "more than one preprocessing.empty allocation in module";
46-
diag.attachNote(emptyOps[0]->getLoc()) << "previous allocation here";
47-
}
48-
signalPassFailure();
49-
// Do NOT return, continue to site pairing checks
50-
}
51-
5259
std::set<uint32_t> siteIds;
5360
for (const auto& [siteId, stores] : storesBySite) {
5461
siteIds.insert(siteId);

lib/Pipelines/ArithmeticPipelineRegistration.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#include "lib/Dialect/Openfhe/Transforms/ConfigureCryptoContext.h"
1717
#include "lib/Dialect/Openfhe/Transforms/CountAddAndKeySwitch.h"
1818
#include "lib/Dialect/Openfhe/Transforms/FastRotationPrecompute.h"
19+
#include "lib/Dialect/Preprocessing/Conversions/PreprocessingToLattigo/PreprocessingToLattigo.h"
20+
#include "lib/Dialect/Preprocessing/Conversions/PreprocessingToOpenfhe/PreprocessingToOpenfhe.h"
21+
#include "lib/Dialect/Preprocessing/Transforms/ValidatePreprocessing.h"
1922
#include "lib/Dialect/Secret/Conversions/SecretToBGV/SecretToBGV.h"
2023
#include "lib/Dialect/Secret/Conversions/SecretToCKKS/SecretToCKKS.h"
2124
#include "lib/Dialect/Secret/Conversions/SecretToModArith/SecretToModArith.h"
@@ -142,6 +145,8 @@ void cleanupAfterLowerAssignLayout(OpPassManager& pm) {
142145
pm.addPass(createCSEPass());
143146
pm.addPass(createRemoveDeadValuesPass());
144147
pm.addPass(createSymbolDCEPass());
148+
pm.addPass(createCanonicalizerPass());
149+
pm.addPass(createCSEPass());
145150
}
146151

147152
// Implement layout conversions as shift networks
@@ -423,9 +428,10 @@ void mlirToRLWEPipeline(OpPassManager& pm,
423428
pm.addPass(lwe::createImplementTrivialEncryptionAsAddition());
424429

425430
// Add a __preprocessed helper for offline pre-packing of plaintexts
426-
auto splitPreprocessingOptions = SplitPreprocessingOptions{};
427-
splitPreprocessingOptions.maxReturnValues = options.splitPreprocessing;
428-
pm.addPass(createSplitPreprocessing(splitPreprocessingOptions));
431+
if (options.enableSplitPreprocessing) {
432+
pm.addPass(createSplitPreprocessing());
433+
pm.addPass(preprocessing::createValidatePreprocessing());
434+
}
429435

430436
ElementwiseToAffineOptions elementwiseOptions;
431437
elementwiseOptions.convertDialects = {"ckks", "bgv", "lwe"};
@@ -471,6 +477,7 @@ BackendPipelineBuilder toOpenFhePipelineBuilder() {
471477

472478
// Convert LWE (and scheme-specific CKKS/BGV ops) to OpenFHE
473479
pm.addPass(lwe::createLWEToOpenfhe());
480+
pm.addPass(preprocessing::createPreprocessingToOpenfhe());
474481
pm.addPass(createCanonicalizerPass());
475482
pm.addPass(createCSEPass());
476483

@@ -513,6 +520,7 @@ BackendPipelineBuilder toLattigoPipelineBuilder() {
513520

514521
// Convert LWE (and scheme-specific BGV ops) to Lattigo
515522
pm.addPass(lwe::createLWEToLattigo());
523+
pm.addPass(preprocessing::createPreprocessingToLattigo());
516524

517525
// Convert Alloc Ops to InPlace Ops
518526
pm.addPass(lattigo::createAllocToInPlace());
@@ -567,7 +575,7 @@ void torchLinalgToCkksBuilder(OpPassManager& manager,
567575
suboptions.ckksBootstrapWaterline = options.ckksBootstrapWaterline;
568576
suboptions.scalingModBits = options.scalingModBits;
569577
suboptions.firstModBits = options.firstModBits;
570-
suboptions.splitPreprocessing = options.splitPreprocessing;
578+
suboptions.enableSplitPreprocessing = options.enableSplitPreprocessing;
571579
suboptions.experimentalDisableLoopUnroll =
572580
options.experimentalDisableLoopUnroll;
573581
suboptions.usePublicKey = options.usePublicKey;

0 commit comments

Comments
 (0)