Issue with mlir-opt

I am getting this error when using the MlirOptMain entry-point however if i use the PassManager's run method, i don’t see the same issue and it actually works. the setup code prior to both entry-points is identical and i am a bit confused as why it doesn’t work with the former. any ideas? or maybe how i could debug this?

LLVM ERROR: can't create type 'mlir::foo::TestType' because storage uniquer isn't initialized: the dialect was likely not loaded.

This has to do with how the context is initialized before calling MlirOptMain, it seems that when you’re calling the PassManager directly, you actually already preloaded the “foo” Dialect in the context.

The pass which create your TestType likely does not declare a dependency on the foo Dialect, see FAQ - MLIR for more information.

So, i actually have two dialects and they do get registered at the same time. i can create the Ops from the first dialect within passes without any issues but cant do the same with the second dialect.

I have now found a workaround which is by using the getDependentDialects method and im assuming this is what you’re pointing at?

But why can I use the first dialect without having to do the above?

The input IR you passing to the PassManager likely already have operations or type from this first dialect, so it is already loaded in the context.

Could you please elaborate a bit. trying to understand how thats happening.

This is the pass:

struct BarPass
    : public PassWrapper<BarPass, OperationPass<ModuleOp>> {

  void runOnOperation() override;
};

And this is how it gets registered:

mlir::PassRegistration<BarPass>(...)

I can access ops from the first dialect in it but not from my second dialect…

Your pass will operate on a Module: anything that is already in the Module before your pass runs necessarily has a dialect registered. So if the input you give to the pass has entities from Dialect1, then it is loaded in the context already.

Now it seems you are trying to create entities (types or operations) defined in Dialect2: this requires you to declare this in the getDependentDialect method.

Thanks a lot. This clarifies it. is there a method to check the current loaded dialects in the Module?

From include/mlir/IR/MLIRContext.h:

class MLIRContext {
public:
  enum class Threading { DISABLED, ENABLED };
  /// Create a new Context.
  explicit MLIRContext(Threading multithreading = Threading::ENABLED);
  explicit MLIRContext(const DialectRegistry &registry,
                       Threading multithreading = Threading::ENABLED);
  ~MLIRContext();
    
  /// Return information about all IR dialects loaded in the context.
  std::vector<Dialect *> getLoadedDialects();

Thanks a lot :slight_smile: