Skip to content

[MLIR][Pass] Full & deterministic diagnostics #110311

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
merged 2 commits into from
Oct 2, 2024
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
12 changes: 7 additions & 5 deletions mlir/lib/Pass/Pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ void OpToOpPassAdaptor::runOnOperationImpl(bool verifyPasses) {
unsigned initGeneration = mgr->impl->initializationGeneration;
if (failed(runPipeline(*mgr, &op, am.nest(&op), verifyPasses,
initGeneration, instrumentor, &parentInfo)))
return signalPassFailure();
signalPassFailure();
}
}
}
Expand Down Expand Up @@ -799,7 +799,8 @@ void OpToOpPassAdaptor::runOnOperationAsyncImpl(bool verifyPasses) {
// An atomic failure variable for the async executors.
std::vector<std::atomic<bool>> activePMs(asyncExecutors.size());
std::fill(activePMs.begin(), activePMs.end(), false);
auto processFn = [&](OpPMInfo &opInfo) {
std::atomic<bool> hasFailure = false;
parallelForEach(context, opInfos, [&](OpPMInfo &opInfo) {
// Find an executor for this operation.
auto it = llvm::find_if(activePMs, [](std::atomic<bool> &isActive) {
bool expectedInactive = false;
Expand All @@ -812,14 +813,15 @@ void OpToOpPassAdaptor::runOnOperationAsyncImpl(bool verifyPasses) {
LogicalResult pipelineResult = runPipeline(
pm, opInfo.op, opInfo.am, verifyPasses,
pm.impl->initializationGeneration, instrumentor, &parentInfo);
if (failed(pipelineResult))
hasFailure.store(true);

// Reset the active bit for this pass manager.
activePMs[pmIndex].store(false);
return pipelineResult;
};
});

// Signal a failure if any of the executors failed.
if (failed(failableParallelForEach(context, opInfos, processFn)))
if (hasFailure)
signalPassFailure();
}

Expand Down
2 changes: 1 addition & 1 deletion mlir/test/Pass/crash-recovery-dynamic-failure.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ module @inner_mod1 {
// REPRO_LOCAL_DYNAMIC_FAILURE: module @inner_mod1
// REPRO_LOCAL_DYNAMIC_FAILURE: module @foo {

// REPRO_LOCAL_DYNAMIC_FAILURE: pipeline: "builtin.module(builtin.module(test-pass-failure))"
// REPRO_LOCAL_DYNAMIC_FAILURE: pipeline: "builtin.module(builtin.module(test-pass-failure{gen-diagnostics=false}))"
17 changes: 17 additions & 0 deletions mlir/test/Pass/full_diagnostics.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(test-pass-failure{gen-diagnostics}))' -verify-diagnostics

// Test that all errors are reported.
// expected-error@below {{illegal operation}}
func.func @TestAlwaysIllegalOperationPass1() {
return
}

// expected-error@below {{illegal operation}}
func.func @TestAlwaysIllegalOperationPass2() {
return
}

// expected-error@below {{illegal operation}}
func.func @TestAlwaysIllegalOperationPass3() {
return
}
12 changes: 11 additions & 1 deletion mlir/test/lib/Pass/TestPassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,21 @@ struct TestCrashRecoveryPass
struct TestFailurePass : public PassWrapper<TestFailurePass, OperationPass<>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestFailurePass)

void runOnOperation() final { signalPassFailure(); }
TestFailurePass() = default;
TestFailurePass(const TestFailurePass &other) : PassWrapper(other) {}

void runOnOperation() final {
signalPassFailure();
if (genDiagnostics)
mlir::emitError(getOperation()->getLoc(), "illegal operation");
}
StringRef getArgument() const final { return "test-pass-failure"; }
StringRef getDescription() const final {
return "Test a pass in the pass manager that always fails";
}

Option<bool> genDiagnostics{*this, "gen-diagnostics",
llvm::cl::desc("Generate a diagnostic message")};
};

/// A test pass that creates an invalid operation in a function body.
Expand Down
Loading