google/mlir-hs

[Usage/Tutorial] Implement the Toy tutorial in Haskell

femtomc opened this issue ยท 8 comments

This seems like a fun thing to do -- especially given how convenient Haskell makes constructing front ends.

If you don't mind, I wouldn't mind working at this for a bit. I'll likely do it outside the repo, but then if it's useful -- it might be included as a small tutorial somewhere.

Sounds great to me! Let me know if you run into any issues. Though doesn't the Toy tutorial declare a new dialect? We don't have the necessary bindings to do that yet, but it's one of the features I would love us to have one day.

Sounds great to me! Let me know if you run into any issues. Though doesn't the Toy tutorial declare a new dialect? We don't have the necessary bindings to do that yet, but it's one of the features I would love us to have one day.

Yes, you're right. I'm also curious about how this might work -- ideally downstream users may not have to write much C++/tablegen to generate new dialects.

I've been a bit away from tracking MLIR development -- I'll peruse the discourse/discord to try and determine if this is possible now.

Last time I thought about this, I think it was my understanding that this functionality would be restricted to the tablegen build phase -- and that sort of functionality would not be exposed via a C API (for example), which might make it convenient to write bindings in other languages. I'm not sure if that has changed.

Yeah I'm not sure if there's a good way to dynamically generate dialects at runtime without invoking the C++ compiler. @jpienaar is that possible/on the roadmap? Interestingly enough I just had a chat about this with some other people yesterday...

You might be interested in the Open Design Meeting (ODM) talk:

2021-06-17: Defining operations, types, attributes, and dialects at runtime ; slides - recording

(Not sure links are working as expected, find it listed at https://mlir.llvm.org/talks/)

I think it may be worthwhile even with a little ODS/tablegen usage in there to show - the majority would still be in Haskell and might identify gaps in the generator here (well we know there are gaps ๐Ÿ™‚)

Right, had a quick convo with Mathieu:

Mathieu Fehr
โ€”
Yesterday at 1:19 PM
This is not possible at the moment as far as I know. MLIR requires you to have a C++ class for your operations, types, and > dialects, so you need to recompile when you change them.
However, I am currently upstreaming changes that would allow defining operations/types/dialects at runtime, and that should allow you to define them from other languages with the right C API.

I also recall Mehdi mentioned this at some point in the newsletter.

I think for now, however, I'm just going to develop the repo as a sort of "good starting point" for new compilers -- where dialect definitions are tablegen'd, and new dialect registration with context options are exposed through a C API. I think there's probably a consistent set of idioms for static dialect construction / registration with downstream languages, and mostly this is the easiest thing to do now.

(Edit: I'm following the idioms from mlir-hs -- e.g. a lightweight AST for language, which implements FromAST, etc)

That sounds great. Also I should add (forgot to) some of the things fr.that talk has landed but not all.

@jpienaar do you mind pointing out how you handled header discovery / inclusion for inline-c?

E.g, I'm writing:

{-# OPTIONS_HADDOCK hide #-}

module Driver where

-- This is the toplevel entry point to the compiler.

import qualified Language.C.Inline as C
import qualified Language.C.Inline.Context as C.Context
import qualified Language.C.Types as C

C.include "toy/Interface.h"

Where I'd like to include calls to a C API. My gut here says that this is organized via Setup.hs -- but I wasn't sure.

Would be greatly appreciated! Thank you.

Edit: I guess I can just pass -I options to GHC directly. I suppose that's actually arranged for convenience in Setup.hs.

You can extend the set of include paths by adding a include-dirs field to the library in your Cabal file. We can't hard-code this for mlir-hs, because the LLVM install location might vary which is why we do this in Setup.hs, but you should be able to get away with a hard-coded value for now.