tensorflow / mlir

"Multi-Level Intermediate Representation" Compiler Infrastructure
1.74k stars 260 forks source link

Running a pass from inside another pass #113

Open bondhugula opened 5 years ago

bondhugula commented 5 years ago

Trying to run a pass (via the pass manager as described in https://github.com/tensorflow/mlir/blob/master/g3doc/WritingAPass.md ) from inside another pass leads to all kinds of crashes and weird behavior, and this is expected since there are passes running concurrently on the same functions at the top level and then at an inner level. It does work when pass threading is disabled (at the top level via command-line).

Could such nesting be disallowed by design somehow? (via the context? - if there is a multi-threaded pass manager already running, new ones invoked could assert).

On another note, even if threading is disabled for the inner pass manager, this still creates problems since the 'run' on the pass manager processes all functions of the module, and so will race with the outer level pass manager that's running in parallel. Is there a reason for not exposing a way to run a pass on a function?

joker-eph commented 5 years ago

On Fri, Aug 30, 2019 at 9:28 AM Uday Bondhugula notifications@github.com wrote:

Trying to run a pass (via the pass manager as described in https://github.com/tensorflow/mlir/blob/master/g3doc/WritingAPass.md ) from inside another pass leads to all kinds of crashes and weird behavior,

It should not be tied to the pass infrastructure (I'd see it as a bug): you should be able to run a pass-manager nested inside another one, I wouldn't expect this to be a problem. However you can't break the contract of the pass you are currently nested in: if you are inside a function pass, you are not allowed to operate on the IR outside of the function itself. Since you can't run (yet, it should be soon) a PassManager on a Function but only on a Module, you would be limited to call a PassManager from a Module pass today.

and this is expected since there are passes running concurrently on the same functions at the top level and then at an inner level. It does work when pass threading is disabled (at the top level via command-line).

Could such nesting be disallowed by design somehow? (via the context? - if there is a multi-threaded pass manager already running, new ones invoked could assert).

We discussed a debug mode to catch this, but we don't have anything satisfactory at the moment. Especially the contract is that you can't modify the IR outside the current IR unit in processing in your pass, this goes beyond nesting PM. Our best tool to catch issues at the moment is TSAN.

On another note, even if threading is disabled for the inner pass manager, this still creates problems since the 'run' on the pass manager processes all functions of the module, and so will race with the outer level pass manager that's running in parallel. Is there a reason for not exposing a way to run a pass on a function?

Generalizing the pass manager to operate on any "isolated" operation is an active area of development, it should be done soon.

-- Mehdi

bondhugula commented 5 years ago

@joker-eph Thanks! I think some of these points could be mentioned in https://github.com/tensorflow/mlir/blob/master/g3doc/WritingAPass.md

joker-eph commented 5 years ago

Which part should we mention? (the doc will be updated with the implementation, but it reflects the current state I believe)

bondhugula commented 5 years ago

Which part should we mention? (the doc will be updated with the implementation, but it reflects the current state I believe)

1) The thing about the contract. 2) The TODO on allowing a pass manager / function pass run on a function.

joker-eph commented 5 years ago

OK, we'll try to make it more clear for 1. It is supposed to be covered in the FunctionPass section. Excerpts:

Function passes have the following restrictions, and any noncompliance will lead to problematic behavior in multithreaded and other advanced scenarios:
 * Modify anything within the parent module, outside of the current function being operated on. 
[...]
 * Access, or modify, the state of another function within the module. Other threads may be operating on different functions within the module.
bondhugula commented 5 years ago

I see - that part is pretty clear then; I had missed it. But the pass manager part could mention that one can't run a pass manager from within another pass since the latter can only be run on modules at the moment.