Skip to content

[mlir][bytecode] Add bytecode writer config API to skip serialization of resources #71991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mlir/include/mlir/Bytecode/BytecodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ class BytecodeWriterConfig {
// Resources
//===--------------------------------------------------------------------===//

/// Set a boolean flag to skip emission of resources into the bytecode file.
void setElideResourceDataFlag(bool shouldElideResourceData = true);

/// Attach the given resource printer to the writer configuration.
void attachResourcePrinter(std::unique_ptr<AsmResourcePrinter> printer);

Expand Down
6 changes: 6 additions & 0 deletions mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ class MlirOptMainConfig {
return *this;
}
bool shouldEmitBytecode() const { return emitBytecodeFlag; }
bool shouldElideResourceDataFromBytecode() const {
return elideResourceDataFromBytecodeFlag;
}

/// Set the IRDL file to load before processing the input.
MlirOptMainConfig &setIrdlFile(StringRef file) {
Expand Down Expand Up @@ -185,6 +188,9 @@ class MlirOptMainConfig {
/// Emit bytecode instead of textual assembly when generating output.
bool emitBytecodeFlag = false;

/// Elide resources when generating bytecode.
bool elideResourceDataFromBytecodeFlag = false;

/// Enable the Debugger action hook: Debugger can intercept MLIR Actions.
bool enableDebuggerActionHookFlag = false;

Expand Down
26 changes: 20 additions & 6 deletions mlir/lib/Bytecode/Writer/BytecodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ struct BytecodeWriterConfig::Impl {
/// Note: This only differs from kVersion if a specific version is set.
int64_t bytecodeVersion = bytecode::kVersion;

/// A flag specifying whether to elide emission of resources into the bytecode
/// file.
bool shouldElideResourceData = false;

/// A map containing dialect version information for each dialect to emit.
llvm::StringMap<std::unique_ptr<DialectVersion>> dialectVersionMap;

Expand Down Expand Up @@ -89,6 +93,11 @@ void BytecodeWriterConfig::attachResourcePrinter(
impl->externalResourcePrinters.emplace_back(std::move(printer));
}

void BytecodeWriterConfig::setElideResourceDataFlag(
bool shouldElideResourceData) {
impl->shouldElideResourceData = shouldElideResourceData;
}

void BytecodeWriterConfig::setDesiredBytecodeVersion(int64_t bytecodeVersion) {
impl->bytecodeVersion = bytecodeVersion;
}
Expand Down Expand Up @@ -1170,29 +1179,33 @@ class ResourceBuilder : public AsmResourceBuilder {
using PostProcessFn = function_ref<void(StringRef, AsmResourceEntryKind)>;

ResourceBuilder(EncodingEmitter &emitter, StringSectionBuilder &stringSection,
PostProcessFn postProcessFn)
PostProcessFn postProcessFn, bool shouldElideData)
: emitter(emitter), stringSection(stringSection),
postProcessFn(postProcessFn) {}
postProcessFn(postProcessFn), shouldElideData(shouldElideData) {}
~ResourceBuilder() override = default;

void buildBlob(StringRef key, ArrayRef<char> data,
uint32_t dataAlignment) final {
emitter.emitOwnedBlobAndAlignment(data, dataAlignment);
if (!shouldElideData)
emitter.emitOwnedBlobAndAlignment(data, dataAlignment);
postProcessFn(key, AsmResourceEntryKind::Blob);
}
void buildBool(StringRef key, bool data) final {
emitter.emitByte(data);
if (!shouldElideData)
emitter.emitByte(data);
postProcessFn(key, AsmResourceEntryKind::Bool);
}
void buildString(StringRef key, StringRef data) final {
emitter.emitVarInt(stringSection.insert(data));
if (!shouldElideData)
emitter.emitVarInt(stringSection.insert(data));
postProcessFn(key, AsmResourceEntryKind::String);
}

private:
EncodingEmitter &emitter;
StringSectionBuilder &stringSection;
PostProcessFn postProcessFn;
bool shouldElideData = false;
};
} // namespace

Expand Down Expand Up @@ -1225,7 +1238,8 @@ void BytecodeWriter::writeResourceSection(Operation *op,

// Builder used to emit resources.
ResourceBuilder entryBuilder(resourceEmitter, stringSection,
appendResourceOffset);
appendResourceOffset,
config.shouldElideResourceData);

// Emit the external resource entries.
resourceOffsetEmitter.emitVarInt(config.externalResourcePrinters.size());
Expand Down
7 changes: 7 additions & 0 deletions mlir/lib/Tools/mlir-opt/MlirOptMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
"emit-bytecode", cl::desc("Emit bytecode when generating output"),
cl::location(emitBytecodeFlag), cl::init(false));

static cl::opt<bool, /*ExternalStorage=*/true> elideResourcesFromBytecode(
"elide-resource-data-from-bytecode",
cl::desc("Elide resources when generating bytecode"),
cl::location(elideResourceDataFromBytecodeFlag), cl::init(false));

static cl::opt<std::optional<int64_t>, /*ExternalStorage=*/true,
BytecodeVersionParser>
bytecodeVersion(
Expand Down Expand Up @@ -385,6 +390,8 @@ performActions(raw_ostream &os,
BytecodeWriterConfig writerConfig(fallbackResourceMap);
if (auto v = config.bytecodeVersionToEmit())
writerConfig.setDesiredBytecodeVersion(*v);
if (config.shouldElideResourceDataFromBytecode())
writerConfig.setElideResourceDataFlag();
return writeBytecodeToFile(op.get(), os, writerConfig);
}

Expand Down
21 changes: 21 additions & 0 deletions mlir/test/Bytecode/resources_elision.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: mlir-opt -emit-bytecode -elide-resource-data-from-bytecode %s | mlir-opt | FileCheck %s

// CHECK-LABEL: @TestDialectResources
module @TestDialectResources attributes {
// CHECK: bytecode.test = dense_resource<decl_resource> : tensor<2xui32>
// CHECK: bytecode.test2 = dense_resource<resource> : tensor<4xf64>
// CHECK: bytecode.test3 = dense_resource<resource_2> : tensor<4xf64>
bytecode.test = dense_resource<decl_resource> : tensor<2xui32>,
bytecode.test2 = dense_resource<resource> : tensor<4xf64>,
bytecode.test3 = dense_resource<resource_2> : tensor<4xf64>
} {}

// CHECK-NOT: dialect_resources
{-#
dialect_resources: {
builtin: {
resource: "0x08000000010000000000000002000000000000000300000000000000",
resource_2: "0x08000000010000000000000002000000000000000300000000000000"
}
}
#-}