### Build and Install MLIR Source: https://github.com/google/mlir-hs/blob/main/README.md Build and install MLIR using the configured CMake settings. This command utilizes the Ninja build system to compile and install MLIR to the specified installation prefix. ```bash cmake --build llvm-project/build -t install ``` -------------------------------- ### Example NameSupplyT Execution Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Shows how to run a NameSupplyT computation using evalNameSupplyT. This example generates two unique names and returns them as a list. ```haskell result <- evalNameSupplyT $ do name1 <- freshName name2 <- freshName return [name1, name2] -- result = ["0", "1"] ``` -------------------------------- ### Building a Simple Module Source: https://github.com/google/mlir-hs/blob/main/_autodocs/02-mlir-ast.md Example of constructing a basic MLIR module with an empty entry block. ```haskell import MLIR.AST let body = Block "0" [] [] modOp = ModuleOp body ``` -------------------------------- ### Example MLIR Value Construction Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Demonstrates how to construct a Value, pairing a string name with an MLIR type. ```haskell let v = "result" :> Float32Type ``` -------------------------------- ### ValueAndBlockMapping Example Source: https://github.com/google/mlir-hs/blob/main/_autodocs/08-mlir-ast-serialize.md Shows the creation of a combined mapping context (ValueAndBlockMapping) for resolving both value and block names. This environment is passed to fromAST for context. ```haskell let env = (valueMap, blockMap) nativeType <- fromAST ctx env astType ``` -------------------------------- ### BlockMapping Example Source: https://github.com/google/mlir-hs/blob/main/_autodocs/08-mlir-ast-serialize.md Demonstrates creating a BlockMapping to map AST block names to native MLIR block references. Essential for resolving control flow successors during conversion. ```haskell let blockMap = M.fromList [ ("entry", nativeEntryBlock), ("exit", nativeExitBlock) ] ``` -------------------------------- ### applyClosedOpRewrite Example Source: https://github.com/google/mlir-hs/blob/main/_autodocs/06-mlir-ast-rewrite.md Example of using applyClosedOpRewrite with a simplification rule to optimize operations. ```haskell import MLIR.AST.Rewrite simplify :: Operation -> Operation simplify = applyClosedOpRewrite simplificationRule where simplificationRule op = case opName op of "arith.addi" | hasZeroOperand op -> ReplaceOne (nonZeroOperand op) _ -> Traverse ``` -------------------------------- ### Start Interactive REPL for mlir-hs Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Command to launch an interactive Haskell environment (GHCi) for the mlir-hs project, allowing for experimentation and debugging. ```bash # Interactive REPL stack ghci ``` -------------------------------- ### RewriteResult Examples Source: https://github.com/google/mlir-hs/blob/main/_autodocs/06-mlir-ast-rewrite.md Illustrates how to use the RewriteResult variants to control the rewriting process. ```haskell -- Replace an operation with its first operand return $ ReplaceOne firstOperand -- Replace with multiple values return $ Replace [val1, val2] -- Keep but continue transforming subregions return Traverse -- Keep unchanged return Skip ``` -------------------------------- ### Affine Map Examples Source: https://github.com/google/mlir-hs/blob/main/_autodocs/07-dialects-affine.md Demonstrates the creation of `Map` data structures with varying dimension and symbol counts, and different sets of affine expressions. Includes type annotations for clarity. ```haskell -- Map with 2 dimensions, 0 symbols, single identity expression let m1 = Map { mapDimensionCount = 2, mapSymbolCount = 0, mapExprs = [Dimension 0] } -- Type: (d0, d1) -> (d0) ``` ```haskell -- Map with 1 dimension, 1 symbol, two expressions let m2 = Map { mapDimensionCount = 1, mapSymbolCount = 1, mapExprs = [ Add (Dimension 0) (Symbol 0), -- d0 + s0 Mul (Constant 2) (Dimension 0) -- 2*d0 ] } -- Type: (d0)[s0] -> (d0+s0, 2*d0) ``` -------------------------------- ### ReplaceOne Example Source: https://github.com/google/mlir-hs/blob/main/_autodocs/06-mlir-ast-rewrite.md Example usage of ReplaceOne for simplifying operations, such as returning an operand when adding zero. ```haskell -- Simplify: return x instead of add(x, 0) return $ ReplaceOne x ``` -------------------------------- ### Example Monad Stack for Block Building Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Illustrates a common monad stack for building blocks, combining `BlockBuilderT`, `NameSupplyT`, and `ReaderT` for environment access within `IO`. ```haskell -- Block builder with name supply and reader context BlockBuilderT (NameSupplyT (ReaderT Env IO)) ``` -------------------------------- ### applyClosedOpRewriteT Example (LLVM Lowering) Source: https://github.com/google/mlir-hs/blob/main/_autodocs/06-mlir-ast-rewrite.md Example of using applyClosedOpRewriteT to lower MLIR operations to LLVM, demonstrating monadic rewrite capabilities. ```haskell import MLIR.AST.Rewrite lowerToLLVM :: Operation -> IO Operation lowerToLLVM = applyClosedOpRewriteT loweringRule where loweringRule op = do case opName op of "memref.alloc" -> do lowered <- emitOp llvmAllocOp return $ ReplaceOne (lowered !! 0) _ -> return Traverse ``` -------------------------------- ### Example Type Extraction Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Shows how to use typeOf to get the MLIR Type from a Value. The result is the MLIR Type itself. ```haskell let ty = typeOf ("x" :> Float32Type) -- ty = Float32Type ``` -------------------------------- ### Monadic Rewrite Example (Lowering) Source: https://github.com/google/mlir-hs/blob/main/_autodocs/06-mlir-ast-rewrite.md An example of a monadic rewrite function that lowers an operation to LLVM equivalents, demonstrating effectful operations. ```haskell lowerMemRef :: OpRewriteM IO lowerMemRef op = do if isMemRefOp op then do -- Generate LLVM equivalents lowered <- emitOp newOp1 return $ ReplaceOne (lowered !! 0) else return Traverse ``` -------------------------------- ### Example: Converting AST Map to Native AffineMap Source: https://github.com/google/mlir-hs/blob/main/_autodocs/07-dialects-affine.md Demonstrates the conversion of an AST `Map` to a native MLIR `AffineMap` using the `fromAST` function. This involves providing the context and initial dimension/symbol counts. ```haskell let m = Map { mapDimensionCount = 1, mapSymbolCount = 1, mapExprs = [Dimension 0, Symbol 0, Add (Dimension 0) (Symbol 0)] } nativeMap <- fromAST ctx (mempty, mempty) m ``` -------------------------------- ### Example Monad Stack for Region Building Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Shows a monad stack for building regions, using `RegionBuilderT` layered over `NameSupplyT` within the `IO` monad. ```haskell -- Region builder with name supply RegionBuilderT (NameSupplyT IO) ``` -------------------------------- ### RewriteBuilderT Usage Example Source: https://github.com/google/mlir-hs/blob/main/_autodocs/06-mlir-ast-rewrite.md Demonstrates using RewriteBuilderT to emit operations and return a rewrite result. ```haskell rule op = RewriteBuilderT $ do results <- emitOp modifiedOp return $ ReplaceOne (results !! 0) ``` -------------------------------- ### Affine Expression Examples Source: https://github.com/google/mlir-hs/blob/main/_autodocs/07-dialects-affine.md Illustrates how to construct various affine expressions using the `Expr` data type, including addition, multiplication, and modulo operations with dimensions, symbols, and constants. ```haskell -- Expression: d0 + d1 Add (Dimension 0) (Dimension 1) ``` ```haskell -- Expression: 2*d0 + s0 (d0 is dimension, s0 is symbol) Add (Mul (Constant 2) (Dimension 0)) (Symbol 0) ``` ```haskell -- Expression: d0 / 4 FloorDiv (Dimension 0) (Constant 4) ``` ```haskell -- Expression: (d0 + d1) % 16 Mod (Add (Dimension 0) (Dimension 1)) (Constant 16) ``` -------------------------------- ### Example Monad Stack for Rewriting Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Demonstrates a complex monad stack for rewriting operations, combining `RewriteBuilderT`, `RewriteT`, and `NameSupplyT` within `IO`. ```haskell -- Rewrite with value/block mappings and name supply RewriteBuilderT IO = BlockBuilderT (RewriteT (NameSupplyT IO)) ``` -------------------------------- ### Example: Converting AST Expr to Native AffineExpr Source: https://github.com/google/mlir-hs/blob/main/_autodocs/07-dialects-affine.md Shows how to use the `fromAST` function to convert an `Expr` value to its native MLIR `AffineExpr` representation. Requires importing necessary modules and providing a context. ```haskell import MLIR.AST.Dialect.Affine import MLIR.Native let expr = Add (Dimension 0) (Constant 1) nativeExpr <- fromAST ctx (mempty, mempty) expr ``` -------------------------------- ### Constant Folding Rewrite Example Source: https://github.com/google/mlir-hs/blob/main/_autodocs/06-mlir-ast-rewrite.md An example of a pure rewrite function that performs constant folding. ```haskell constantFolder :: OpRewrite constantFolder op = if isConstantFoldable op then return $ ReplaceOne foldedValue else return Traverse ``` -------------------------------- ### MLIR AST Serialization Source: https://github.com/google/mlir-hs/blob/main/_autodocs/COMPLETION_SUMMARY.txt Documentation on AST-to-native type conversion, the `FromAST` typeclass implementation guide, and array packing and utility functions for serialization. ```APIDOC ## MLIR AST Serialization ### Description This section covers the serialization capabilities of the MLIR-HS AST, focusing on AST-to-native type conversion. It includes a guide to implementing the `FromAST` typeclass and details array packing and utility functions. ### Modules Documented - MLIR.AST.Serialize (100% coverage, 11 items) ### Key API Elements - AST to native type conversion - `FromAST` typeclass implementation - Array packing utilities ``` -------------------------------- ### Running Specific Tests Source: https://github.com/google/mlir-hs/blob/main/_autodocs/10-project-structure.md Command to run a specific test module, for example, 'ASTSpec', using the stack build tool. ```bash stack test --ta "-m ASTSpec" ``` -------------------------------- ### ValueMapping Example Source: https://github.com/google/mlir-hs/blob/main/_autodocs/08-mlir-ast-serialize.md Illustrates creating a ValueMapping to associate AST variable names with native MLIR value references. Used for resolving operand references during AST-to-native conversion. ```haskell let valueMap = M.fromList [ ("x", nativeValX), ("y", nativeValY) ] ``` -------------------------------- ### Example Operand Name Conversion Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Illustrates the usage of the operands function to convert a list of Values into a list of Names. ```haskell let names = operands [v1, v2, v3] ``` -------------------------------- ### Example Fresh Name Generation Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Demonstrates generating unique names using the freshName function within a MonadNameSupply context. The generated names are guaranteed to be unique. ```haskell n1 <- freshName n2 <- freshName -- n1 and n2 are unique ``` -------------------------------- ### Example Fresh Value Generation Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Demonstrates generating a fresh Value of type Float32Type. The generated value will have a unique name prefixed with '0'. ```haskell v <- freshValue Float32Type -- v = "0" :> Float32Type ``` -------------------------------- ### Example Fresh Block Argument Generation Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Illustrates creating a fresh block argument of type Float32Type. The generated value will have a name like 'arg0'. ```haskell arg <- freshBlockArg Float32Type -- arg = "arg0" :> Float32Type ``` -------------------------------- ### Example Operation Emission Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Shows how to emit an MLIR operation that does not return any results using the emitOp_ function. This is used for side-effecting operations. ```haskell emitOp_ $ someOpWithNoResults ``` -------------------------------- ### createEmptyModule Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Creates a new, empty MLIR module at a specified source location. This is the starting point for building a module programmatically. ```APIDOC ## createEmptyModule ### Description Create a new empty module in a specific location. ### Signature ```haskell createEmptyModule :: Location -> IO Module ``` ### Parameters #### Parameters - **loc** (`Location`) - Required - Module source location ### Returns Empty `Module` ### Example ```haskell loc <- getUnknownLocation ctx mod <- createEmptyModule loc -- populate module destroyModule mod ``` ``` -------------------------------- ### Configure MLIR Build with CMake Source: https://github.com/google/mlir-hs/blob/main/README.md Configure the MLIR build using CMake. This command specifies the build system (Ninja), enables the MLIR project, sets the installation prefix, and builds shared libraries for MLIR and LLVM. ```bash cmake -B llvm-project/build \ -G Ninja \ -DLLVM_ENABLE_PROJECTS=mlir \ -DCMAKE_INSTALL_PREFIX=$PREFIX \ -DMLIR_BUILD_MLIR_C_DYLIB=ON \ -DLLVM_BUILD_LLVM_DYLIB=ON \ llvm-project/llvm ``` -------------------------------- ### Pass Execution Order Example Source: https://github.com/google/mlir-hs/blob/main/_autodocs/04-mlir-native-pass.md Illustrates the sequential execution of MLIR passes. Passes are executed in the order they are added to the pass manager, with reconciliation passes typically run last. ```haskell withPassManager ctx \pm -> do addConvertArithToLLVMPass pm -- runs first addConvertMemRefToLLVMPass pm -- runs second addConvertReconcileUnrealizedCastsPass pm -- runs third runPasses pm op ``` -------------------------------- ### Run Block Builder Computation Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Extracts arguments and bindings from a block builder computation. Use this to get the results of a block building process. ```haskell (result, (blockArgs, blockOps)) <- runBlockBuilder $ do arg <- blockArgument Float32Type results <- emitOp someOp return results ``` -------------------------------- ### Example: Converting AST Type to Native Type Source: https://github.com/google/mlir-hs/blob/main/_autodocs/02-mlir-ast.md Demonstrates how to use the fromAST function to convert an AST Type (Float32Type) to its native MLIR type representation. ```haskell let astType = Float32Type nativeType <- fromAST ctx (mempty, mempty) astType ``` -------------------------------- ### MLIR-HS Module Documentation Overview Source: https://github.com/google/mlir-hs/blob/main/_autodocs/COMPLETION_SUMMARY.txt This section outlines the structure and content of the MLIR-HS API documentation, which is organized into multiple markdown files for clarity. It details the types of information provided for each module, including function signatures, parameter tables, return types, code examples, and source references. ```APIDOC ## MLIR-HS Documentation Structure ### Overview The MLIR-HS project provides comprehensive API documentation in markdown format, organized by module and type. ### Content Details - **Full Signatures**: Includes parameter types for all exported functions. - **Parameter Tables**: Detailed descriptions for each parameter. - **Return Types**: Documentation for the return type of functions. - **Code Examples**: Practical examples for each function. - **Source References**: Links to the source file and line number. - **Cross-References**: Links to related documentation items. ### Module Documentation Each public module is documented in its own `.md` file, covering its specific API details. ### Type Reference A dedicated `types.md` file documents all named types and their fields. ### Navigation - `README.md`: Project overview and navigation. - `09-quick-start.md`: Installation and getting started guide. - `types.md`: Type reference. - Module-specific docs (`01-11`): API details. - `10-project-structure.md`: Architecture overview. - `INDEX.md`: Cross-reference lookup. ### Compliance - 100% of exported functions, classes, methods, modules, and types are documented. - Documentation focuses on exported symbols only. - No invented content or marketing copy. - Markdown format, plain markdown, no HTML/CSS. - Top-level headings for each document. ``` -------------------------------- ### Build MLIR IR with Monads Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Shows how to construct MLIR Intermediate Representation (IR) using monadic builders. This example builds a simple function with a single argument. Requires `MLIR.AST.Builder` and `Data.Map.Strict`. ```haskell import MLIR.AST.Builder import qualified Data.Map.Strict as M let modOp = evalNameSupplyT $ buildModule $ do buildSimpleFunction "main" [] M.empty $ do arg <- blockArgument Float32Type return EndOfBlock ``` -------------------------------- ### Create Empty MLIR Module Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Creates a new, empty MLIR module at a specified source location. This is the starting point for building new MLIR structures. ```haskell createEmptyModule :: Location -> IO Module loc <- getUnknownLocation ctx mod <- createEmptyModule loc -- populate module destroyModule mod ``` -------------------------------- ### MLIR Execution Engine Return Type Examples Source: https://github.com/google/mlir-hs/blob/main/_autodocs/05-mlir-native-execution-engine.md Illustrates the expected return types for `executionEngineInvoke` when dealing with different Storable Haskell types. Ensures correct type matching for successful retrieval of results. ```haskell executionEngineInvoke eng nameRef args :: IO (Maybe Int64) ``` ```haskell executionEngineInvoke eng nameRef args :: IO (Maybe Float) ``` ```haskell executionEngineInvoke eng nameRef args :: IO (Maybe Bool) ``` -------------------------------- ### Create and Inspect MLIR Module Natively Source: https://github.com/google/mlir-hs/blob/main/_autodocs/09-quick-start.md Demonstrates creating an empty MLIR module, inspecting its body and operations, and printing its assembly representation using native bindings. ```haskell import MLIR.Native import qualified Data.ByteString as BS example :: IO () example = withContext \ctx -> do registerAllDialects ctx -- Create empty module loc <- getUnknownLocation ctx mod <- createEmptyModule loc -- Get module info body <- getModuleBody mod ops <- getBlockOperations body putStrLn $ "Module has " ++ show (length ops) ++ " operations" -- Print module output <- showModule mod BS.putStr output destroyModule mod ``` -------------------------------- ### Build MLIR AST, Convert to Native, and JIT Execute Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md This snippet illustrates building an MLIR module, converting it to a native format, and then executing it using a JIT compiler. It requires an `ExecutionEngine` and a function name (e.g., `"main"`). ```haskell let astOp = evalNameSupplyT $ buildModule $ ... nativeOp <- fromAST ctx (mempty, mempty) astOp -- convert to module... withExecutionEngine mod \case Just eng -> executionEngineInvoke eng "main" [] Nothing -> return Nothing ``` -------------------------------- ### showModule Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Formats a module into its MLIR assembly string representation. ```APIDOC ## showModule ### Description Format a module as an MLIR assembly string. ### Method N/A (Haskell function) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```haskell output <- showModule mod BS.putStr output ``` ### Response #### Success Response - **ByteString** (ByteString) - MLIR assembly representation #### Response Example N/A ``` -------------------------------- ### Create and Use MLIR Context Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Demonstrates how to create an MLIR context, register all dialects, and then use the context for further operations. Ensure `MLIR.Native` is imported. ```haskell import MLIR.Native withContext \ctx -> do registerAllDialects ctx -- use context ``` -------------------------------- ### Build MLIR AST, Apply Rewrite Rule, and Display Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md This workflow demonstrates building an MLIR module from an AST, applying a rewrite rule using `applyClosedOpRewrite`, converting the result to a native operation, and displaying it. Ensure the rewrite rule (`myRule`) is defined. ```haskell let astOp = evalNameSupplyT $ buildModule $ ... let optimized = applyClosedOpRewrite myRule astOp nativeOp <- fromAST ctx (mempty, mempty) optimized output <- showOperation nativeOp BS.putStr output ``` -------------------------------- ### Get Operation Regions Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Retrieves all regions associated with a given MLIR operation. This is fundamental for navigating the structure of complex operations. ```haskell getOperationRegions :: Operation -> IO [Region] regions <- getOperationRegions op mapM_ processRegion regions ``` -------------------------------- ### Execute MLIR Module with JIT Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Shows how to initialize an execution engine for a given MLIR module and invoke a function within it. Handles potential JIT compilation failures. Requires `MLIR.Native.ExecutionEngine`. ```haskell import MLIR.Native.ExecutionEngine withExecutionEngine mod \case Just eng -> do result <- executionEngineInvoke eng "func" [] Nothing -> putStrLn "JIT compilation failed" ``` -------------------------------- ### Create MLIR Build Directory Source: https://github.com/google/mlir-hs/blob/main/README.md Create a temporary directory for building MLIR. This directory will contain the build artifacts. ```bash mkdir llvm-project/build ``` -------------------------------- ### Get Block Operations Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Retrieves all operations contained within a specific MLIR block. This allows for iterating through and processing operations sequentially. ```haskell getBlockOperations :: Block -> IO [Operation] ops <- getBlockOperations block mapM_ showOperation ops ``` -------------------------------- ### createExecutionEngine Source: https://github.com/google/mlir-hs/blob/main/_autodocs/05-mlir-native-execution-engine.md Creates a Just-In-Time (JIT) execution engine for a given MLIR module. It compiles the module with aggressive optimization (level 3) and assumes the module contains valid LLVM-compatible operations. The engine takes ownership of the module. ```APIDOC ## createExecutionEngine ### Description Create a JIT execution engine for a module. ### Method `createExecutionEngine :: Module -> IO (Maybe ExecutionEngine)` ### Parameters #### Path Parameters - **m** (`Module`) - Required - MLIR module to compile ### Returns - `Maybe ExecutionEngine` - Execution engine on success, `Nothing` on compilation failure ### Details - Optimization level is fixed at 3 (aggressive optimization) - The module must contain valid LLVM-compatible operations - The engine takes ownership of the module ### Example ```haskell mod <- createEmptyModule loc -- populate module with operations... eng <- createExecutionEngine mod case eng of Just e -> do result <- executionEngineInvoke e functionName [arg1, arg2] destroyExecutionEngine e Nothing -> putStrLn "JIT compilation failed" ``` ``` -------------------------------- ### Running All Tests Source: https://github.com/google/mlir-hs/blob/main/_autodocs/10-project-structure.md Command to execute the entire test suite using the stack build tool. ```bash stack test ``` -------------------------------- ### Build MLIR Pipeline: AST to Native Module Source: https://github.com/google/mlir-hs/blob/main/_autodocs/08-mlir-ast-serialize.md Illustrates a common pattern for building an MLIR pipeline: creating an AST module, converting it to its native representation using `fromAST`, and then using the native representation. ```haskell -- 1. Create AST let astModule = ModuleOp (Block "0" [] []) -- 2. Convert to native nativeModule <- do nativeOp <- fromAST ctx (mempty, mempty) astModule moduleFromOperation nativeOp -- 3. Use native representation output <- showModule nativeModule BS.putStr output ``` -------------------------------- ### Test Suite Organization Source: https://github.com/google/mlir-hs/blob/main/_autodocs/10-project-structure.md Illustrates the directory structure for the project's test suite. Includes the main entry point and subdirectories for different testing modules. ```bash test/ ├── Spec.hs # hspec entry point └── MLIR/ ├── ASTSpec.hs # Test AST types and conversions ├── BuilderSpec.hs # Test builder monad ├── NativeSpec.hs # Test native API ├── RewriteSpec.hs # Test rewrite machinery └── Test/ └── Generators.hs # QuickCheck generators ``` -------------------------------- ### Get Number of Loaded Dialects Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Queries the number of dialects currently registered in an MLIR context. Useful for verifying dialect registration or for debugging. ```haskell numDialects <- getNumLoadedDialects ctx putStrLn $ "Dialects: " ++ show numDialects ``` -------------------------------- ### Safe AST Conversion with Resource Management Source: https://github.com/google/mlir-hs/blob/main/_autodocs/08-mlir-ast-serialize.md Shows how to perform AST to native conversion safely using `withContext` to ensure proper resource management (e.g., MLIR context cleanup). ```haskell convertAST :: AST.Operation -> IO Native.Operation convertAST astOp = do withContext \ctx -> do fromAST ctx (mempty, mempty) astOp ``` -------------------------------- ### Build MLIR AST, Convert to Native, and Apply Passes Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md This workflow shows building an MLIR module from an AST, converting it to a native representation, and then running passes like `ConvertArithToLLVM`. It requires a context and a pass manager. ```haskell let astOp = evalNameSupplyT $ buildModule $ ... nativeOp <- fromAST ctx (mempty, mempty) astOp -- convert to module... withPassManager ctx \pm -> do addConvertArithToLLVMPass pm runPasses pm nativeOp ``` -------------------------------- ### Get Module Body Block Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Retrieves the root Block that contains module-level definitions. This is useful for accessing top-level constructs within an MLIR module. ```haskell getModuleBody :: Module -> IO Block ``` -------------------------------- ### Get Region Blocks Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Fetches all basic blocks contained within a specific MLIR region. Essential for analyzing control flow within a region. ```haskell getRegionBlocks :: Region -> IO [Block] ``` -------------------------------- ### Apply MLIR Passes Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Demonstrates how to set up a pass manager, add a specific conversion pass (Arith to LLVM), and then run the passes on an operation. Requires `MLIR.Native.Pass`. ```haskell import MLIR.Native.Pass withPassManager ctx \pm -> do addConvertArithToLLVMPass pm runPasses pm op ``` -------------------------------- ### Building Blocks with Bindings Source: https://github.com/google/mlir-hs/blob/main/_autodocs/02-mlir-ast.md Shows how to create a block with named operation bindings, associating operation results with identifiers. ```haskell let ops = [ "v0" := op1, "v1" := op2 ] block = Block "entry" [] ops ``` -------------------------------- ### Build Simple Module with One Function Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Demonstrates building a simple MLIR module containing a single function using `buildModule` and `buildSimpleFunction`. Includes necessary imports and execution context. ```haskell import MLIR.AST.Builder import qualified Data.Map.Strict as M main :: IO () main = do let modOp = evalNameSupplyT $ buildModule $ do buildSimpleFunction "identity" [Float32Type] M.empty $ do x <- blockArgument Float32Type return EndOfBlock print modOp ``` -------------------------------- ### Execute a Simple MLIR Function Source: https://github.com/google/mlir-hs/blob/main/_autodocs/05-mlir-native-execution-engine.md Demonstrates how to create a context, module, and execution engine to invoke a named function with arguments. Ensure the module is populated with the target function definition. ```haskell import MLIR.Native import MLIR.Native.ExecutionEngine executeFunction :: String -> Float -> Float -> IO (Maybe Float) executeFunction funcName x y = do ctx <- createContext loc <- getUnknownLocation ctx mod <- createEmptyModule loc -- populate mod with operations... -- (assumed to define the function) result <- withExecutionEngine mod \case Just eng -> do withStringRef funcName \nameRef -> do executionEngineInvoke eng nameRef [SomeStorable x, SomeStorable y] Nothing -> return Nothing destroyContext ctx return result ``` -------------------------------- ### Build Module with Multiple Functions Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Illustrates constructing an MLIR module with multiple functions, including declaring a helper function and defining a main function with operations. Shows the use of `declareFunction`, `buildSimpleFunction`, `emitOp`, and `terminateBlock`. ```haskell evalNameSupplyT $ buildModule $ do declareFunction "helper" (FunctionType [Float32Type] [Float32Type]) buildSimpleFunction "main" [] M.empty $ do x <- emitOp constantOp y <- emitOp (callOp "helper" [x]) emitOp_ (printOp [y]) terminateBlock ``` -------------------------------- ### Safe Context Management Source: https://github.com/google/mlir-hs/blob/main/_autodocs/09-quick-start.md Demonstrates the use of `withContext` for automatic resource management, contrasting it with manual `createContext` and `destroyContext`. ```haskell -- Good: context is automatically destroyed withContext \ctx -> do registerAllDialects ctx -- work with ctx -- Avoid: manual resource management ctx <- createContext registerAllDialects ctx -- work with ctx destroyContext ctx -- easy to forget ``` -------------------------------- ### Run Block Builder with Operation Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Demonstrates running a block builder computation and emitting an operation with a specific operand. This is useful for constructing blocks with defined operations. ```haskell (retVal, (args, ops)) <- runBlockBuilder $ do arg <- blockArgument Float32Type emitOp (someOp { opOperands = [operand arg] }) ``` -------------------------------- ### FromAST Typeclass Usage Source: https://github.com/google/mlir-hs/blob/main/_autodocs/08-mlir-ast-serialize.md Example of using the FromAST typeclass to convert a Haskell AST type (Float32Type) to its native MLIR representation. It utilizes the MLIR context and an empty mapping environment. ```haskell import MLIR.AST import MLIR.AST.Serialize import qualified MLIR.Native as Native let astType = Float32Type nativeType <- fromAST ctx (mempty, mempty) astType -- nativeType :: Native.Type ``` -------------------------------- ### Building a Module with Source Locations Source: https://github.com/google/mlir-hs/blob/main/_autodocs/03-mlir-ast-builder.md Demonstrates how to set a default source location for operations built within a monadic context. This is useful for associating generated MLIR code with its origin. ```haskell withContext \ctx -> do loc <- getUnknownLocation ctx evalNameSupplyT $ buildModule $ do setDefaultLocation loc buildSimpleFunction "test" [] M.empty $ do arg <- blockArgument Float32Type terminateBlock ``` -------------------------------- ### Convert Simple Bool Type with FromAST Source: https://github.com/google/mlir-hs/blob/main/_autodocs/08-mlir-ast-serialize.md Example implementation of `FromAST` for converting a Haskell `Bool` to a native MLIR boolean type. It maps `True` to 1 and `False` to 0 for the C API. ```haskell instance FromAST Bool Native.SomeBoolType where fromAST ctx env b = do let cValue = if b then 1 else 0 [C.exp| MlirBool { mlirBoolCreate($(int cValue)) } |] ``` -------------------------------- ### Create an MLIR JIT Execution Engine Source: https://github.com/google/mlir-hs/blob/main/_autodocs/05-mlir-native-execution-engine.md Creates a JIT execution engine for an MLIR module. The module must contain valid LLVM-compatible operations. Optimization level is fixed at 3. ```haskell createExecutionEngine :: Module -> IO (Maybe ExecutionEngine) ``` ```haskell mod <- createEmptyModule loc -- populate module with operations... eng <- createExecutionEngine mod case eng of Just e -> do result <- executionEngineInvoke e functionName [arg1, arg2] destroyExecutionEngine e Nothing -> putStrLn "JIT compilation failed" ``` -------------------------------- ### Creating an Affine Map Attribute Source: https://github.com/google/mlir-hs/blob/main/_autodocs/07-dialects-affine.md Demonstrates how to create an AffineMapAttr by first defining an Affine Map with dimensions and then embedding it into an attribute. ```haskell import MLIR.AST let affineMap = Map 2 0 [Dimension 0, Dimension 1] attr = AffineMapAttr affineMap ``` -------------------------------- ### Build and Test MLIR Haskell Source: https://github.com/google/mlir-hs/blob/main/_autodocs/09-quick-start.md Builds the MLIR Haskell project using Stack and optionally runs tests. Assumes MLIR is built from source and llvm-config is in the PATH. ```bash stack build stack test # Optional: run tests ``` -------------------------------- ### showOperation Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Formats an MLIR operation into its assembly string representation using the MLIR printer. This provides a human-readable view of the operation. ```APIDOC ## showOperation ### Description Format an operation as an MLIR assembly string using the MLIR printer. ### Signature ```haskell showOperation :: Operation -> IO ByteString ``` ### Parameters #### Parameters - **op** (`Operation`) - Required - Operation to format ### Returns MLIR assembly representation ### Example ```haskell let op = ... -- some operation output <- showOperation op BS.putStr output ``` ``` -------------------------------- ### Build mlir-hs Library Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Command to build the mlir-hs library using Haskell Stack. Assumes MLIR and `llvm-config` are correctly set up in the PATH. ```bash # Prerequisites: MLIR built from source, llvm-config in PATH # Build the library stack build ``` -------------------------------- ### Convert Composite Type with FromAST Source: https://github.com/google/mlir-hs/blob/main/_autodocs/08-mlir-ast-serialize.md Example implementation of `FromAST` for converting a Haskell list of `MyType` to a native MLIR array type. It uses `packFromAST` to handle the list elements and then calls the MLIR C API to create the array. ```haskell instance FromAST [MyType] Native.ArrayType where fromAST ctx env items = evalContT $ do (numItems, itemsPtr) <- packFromAST ctx env items liftIO $ [C.exp| MlirArray { mlirArrayCreate($(MlirContext ctx), $(intptr_t numItems), $(MlirMyType* itemsPtr)) } |] ``` -------------------------------- ### MLIR Native C API Bindings Source: https://github.com/google/mlir-hs/blob/main/_autodocs/COMPLETION_SUMMARY.txt Documentation for the native MLIR C API bindings, covering context, operation, module, region, and block management, along with debugging and utility functions. ```APIDOC ## MLIR Native C API Bindings ### Description This section details the native MLIR C API bindings available in Haskell. It covers fundamental APIs for managing MLIR contexts, operations, modules, regions, and blocks, as well as essential debugging and utility functions. ### Modules Documented - MLIR.Native (100% coverage, 31 exported items) ### Key API Elements - Context management - Operation manipulation - Module and region APIs - Block construction and traversal - Debugging utilities ``` -------------------------------- ### withExecutionEngine Source: https://github.com/google/mlir-hs/blob/main/_autodocs/05-mlir-native-execution-engine.md Provides a resource-safe way to use an execution engine. It creates an engine, performs a given action with it, and ensures the engine is automatically destroyed afterward, even if errors occur. ```APIDOC ## withExecutionEngine ### Description Resource-safe wrapper for execution engine operations. ### Method `withExecutionEngine :: Module -> (Maybe ExecutionEngine -> IO a) -> IO a` ### Parameters #### Path Parameters - **m** (`Module`) - Required - MLIR module - **action** (`Maybe ExecutionEngine -> IO a`) - Required - Computation using engine ### Returns - `IO a` - Result of the action; engine is automatically destroyed ### Example ```haskell withExecutionEngine mod \case Just eng -> do result <- executionEngineInvoke eng "main" [] putStrLn $ "Result: " ++ show result Nothing -> putStrLn "JIT compilation failed" ``` ``` -------------------------------- ### Build Simple Function with Builder Source: https://github.com/google/mlir-hs/blob/main/_autodocs/09-quick-start.md Creates an MLIR context, registers dialects, and builds a simple function named 'square' that takes a Float32 argument using the AST Builder. ```haskell {-# LANGUAGE OverloadedStrings #} import qualified Data.Map.Strict as M import Data.ByteString (ByteString) import MLIR.AST import MLIR.AST.Builder import MLIR.Native import qualified Data.ByteString as BS main :: IO () main = do -- Create MLIR context withContext \ctx -> do -- Register all dialects registerAllDialects ctx -- Build a simple function let modOp = evalNameSupplyT $ buildModule $ do buildSimpleFunction "square" [Float32Type] M.empty $ do x <- blockArgument Float32Type return EndOfBlock -- Print the module case modOp of ModuleOp body -> do let block = case body of Block _ _ ops -> body print block ``` -------------------------------- ### showBlock Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Formats an MLIR basic block into its assembly string representation. This provides a human-readable view of the block's contents. ```APIDOC ## showBlock ### Description Format a block as an MLIR assembly string. ### Signature ```haskell showBlock :: Block -> IO ByteString ``` ### Parameters #### Parameters - **block** (`Block`) - Required - Block to format ### Returns MLIR assembly representation ``` -------------------------------- ### MLIR Native Execution Engine Source: https://github.com/google/mlir-hs/blob/main/_autodocs/COMPLETION_SUMMARY.txt Information on Just-In-Time (JIT) compilation and function invocation using the execution engine, featuring type-safe execution with `SomeStorable` and struct packing utilities. ```APIDOC ## MLIR Native Execution Engine ### Description This section covers the Just-In-Time (JIT) compilation and function invocation capabilities of the MLIR-HS execution engine. It highlights type-safe execution using `SomeStorable` and details utilities for struct packing. ### Modules Documented - MLIR.Native.ExecutionEngine (100% coverage, 6 items) ### Key API Elements - JIT compilation - Function invocation - `SomeStorable` for type-safe execution - Struct packing utilities ``` -------------------------------- ### Parse, Inspect, and Display MLIR Module Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md This snippet demonstrates parsing an MLIR string, iterating through its operations, and displaying them. Ensure MLIR context and dialects are registered before use. ```haskell withContext \ctx -> do registerAllDialects ctx withStringRef mlirCode \codeRef -> do Just mod <- parseModule ctx codeRef ops <- getBlockOperations =<< getModuleBody mod forM_ ops \op -> do output <- showOperation op BS.putStr output destroyModule mod ``` -------------------------------- ### Create and Destroy MLIR Context Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Demonstrates the creation of a new MLIR context and its subsequent destruction to release resources. Always ensure contexts are destroyed after use. ```haskell import MLIR.Native ctx <- createContext -- use ctx destroyContext ctx ``` -------------------------------- ### Compose and Run MLIR Pass Pipeline Source: https://github.com/google/mlir-hs/blob/main/_autodocs/04-mlir-native-pass.md Demonstrates composing a custom pass pipeline, including initial custom passes followed by standard lowering passes to LLVM. Use this to define a sequence of operations for compilation. ```haskell runPipeline :: Operation -> IO () runPipeline op = do ctx <- getContext op result <- withPassManager ctx \pm -> do -- Apply custom passes first -- addCustomPass pm -- Then lowering addConvertArithToLLVMPass pm addConvertMemRefToLLVMPass pm addConvertReconcileUnrealizedCastsPass pm runPasses pm op case result of Success -> do output <- showOperation op BS.putStr output Failure -> putStrLn "Compilation failed" ``` -------------------------------- ### Build Block with Arguments Source: https://github.com/google/mlir-hs/blob/main/_autodocs/09-quick-start.md Constructs a simple MLIR block that accepts two Float32 arguments using the AST Builder. ```haskell import MLIR.AST.Builder buildSampleBlock :: IO Block buildSampleBlock = evalNameSupplyT $ soleBlock $ do x <- blockArgument Float32Type y <- blockArgument Float32Type return EndOfBlock ``` -------------------------------- ### Run mlir-hs Tests Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Command to execute the test suite for the mlir-hs project using Haskell Stack. This verifies the correctness of the library's components. ```bash # Run tests stack test ``` -------------------------------- ### MLIR Native Pass Manager Source: https://github.com/google/mlir-hs/blob/main/_autodocs/COMPLETION_SUMMARY.txt Details on the pass manager lifecycle and execution, including documentation for 7 LLVM conversion passes and patterns for pipeline composition. ```APIDOC ## MLIR Native Pass Manager ### Description This document explains the pass manager lifecycle and execution within MLIR-HS. It includes documentation for 7 specific LLVM conversion passes and outlines patterns for composing transformation pipelines. ### Modules Documented - MLIR.Native.Pass (100% coverage, 11 items) ### Key API Elements - Pass manager lifecycle - LLVM conversion passes - Pipeline composition ``` -------------------------------- ### Builder Monad for IR Construction Source: https://github.com/google/mlir-hs/blob/main/_autodocs/09-quick-start.md Illustrates using the `evalNameSupplyT` and `buildModule` for automatic name management in complex IR construction, compared to manual threading. ```haskell -- Good: automatic name management let modOp = evalNameSupplyT $ buildModule $ do x <- blockArgument Float32Type y <- blockArgument Float32Type z <- emitOp someOp return () -- Avoid: manual name threading let n1 = "0" n2 = "1" n3 = "2" -- tedious... ``` -------------------------------- ### Clone LLVM Project Repository Source: https://github.com/google/mlir-hs/blob/main/README.md Clone the latest LLVM code into the root of the mlir-hs repository. This is the first step in building MLIR from source. ```bash git clone https://github.com/llvm/llvm-project ``` -------------------------------- ### MLIR AST Builder API Source: https://github.com/google/mlir-hs/blob/main/_autodocs/COMPLETION_SUMMARY.txt Documentation for the monadic IR construction API, including `NameSupplyT`, `BlockBuilderT`, and `RegionBuilderT`, with 19 documented functions and builders for common building patterns. ```APIDOC ## MLIR AST Builder API ### Description This section covers the monadic Intermediate Representation (IR) construction API, featuring `NameSupplyT`, `BlockBuilderT`, and `RegionBuilderT`. It documents 19 functions and builders, illustrating common patterns for constructing MLIR IR. ### Modules Documented - MLIR.AST.Builder (100% coverage, 19 items) ### Key API Elements - Monadic IR construction - `NameSupplyT`, `BlockBuilderT`, `RegionBuilderT` - Documented functions and builders - Common building patterns ``` -------------------------------- ### packFromAST for C Array Conversion Source: https://github.com/google/mlir-hs/blob/main/_autodocs/08-mlir-ast-serialize.md Demonstrates using packFromAST to convert a list of AST values to native types and pack them into a C array. The resulting pointer and count are used in a C API call, e.g., mlirTupleTypeGet. ```haskell import Control.Monad.Trans.Cont evalContT $ do (numTypes, typesPtr) <- packFromAST ctx env astTypes liftIO $ do -- Use numTypes and typesPtr in C API call result <- [C.exp| MlirType { mlirTupleTypeGet($(MlirContext ctx), $(intptr_t numTypes), $(MlirType* typesPtr)) } | return result ``` -------------------------------- ### Map to Native AffineMap Conversion Instance Source: https://github.com/google/mlir-hs/blob/main/_autodocs/07-dialects-affine.md Declares the `FromAST` instance for converting `Map` to native MLIR `AffineMap`. This enables the conversion of AST-based affine maps to their MLIR C API equivalents. ```haskell instance FromAST Map Native.AffineMap ``` -------------------------------- ### withContext Source: https://github.com/google/mlir-hs/blob/main/_autodocs/01-mlir-native.md Provides a resource-safe way to use an MLIR context. It automatically creates a new context, passes it to the provided IO action, and ensures the context is destroyed upon completion, whether successful or due to an error. ```APIDOC ## withContext ### Description Resource-safe wrapper providing an IO action with a fresh context. The context is automatically destroyed after the action completes. ### Parameters #### Path Parameters - **action** (`Context -> IO a`) - Required - Computation requiring a context ### Returns Result of the action ### Example ```haskell withContext \ctx -> do registerAllDialects ctx -- use ctx return result ``` ``` -------------------------------- ### Defining Loop Bounds with Affine Maps Source: https://github.com/google/mlir-hs/blob/main/_autodocs/07-dialects-affine.md Illustrates the creation of Affine Maps for loop bounds, including a constant lower bound (0) and an upper bound defined by a symbol 'N'. Requires importing MLIR.AST.Dialect.Affine and Data.Map.Strict. ```haskell import MLIR.AST.Dialect.Affine import qualified Data.Map.Strict as M -- Lower bound: 0 lowerBound = Map { mapDimensionCount = 0, mapSymbolCount = 0, mapExprs = [Constant 0] } -- Upper bound: N (a symbol) upperBound = Map { mapDimensionCount = 0, mapSymbolCount = 1, mapExprs = [Symbol 0] -- N is symbol 0 } attrs = M.fromList [ ("lower_bound", AffineMapAttr lowerBound), ("upper_bound", AffineMapAttr upperBound) ] ``` -------------------------------- ### Enable Debug Mode Source: https://github.com/google/mlir-hs/blob/main/_autodocs/09-quick-start.md Shows how to enable MLIR debug output using `setDebugMode True`. Errors will be printed to stderr. ```haskell import MLIR.Native (setDebugMode) main :: IO () main = do setDebugMode True -- Enable MLIR debug output -- Run operations that might fail -- Errors will be printed to stderr ``` -------------------------------- ### Inline-C Usage for Embedding C Code Source: https://github.com/google/mlir-hs/blob/main/_autodocs/10-project-structure.md Demonstrates how to embed C code directly within Haskell using the inline-c library. Requires MLIR C headers and libraries to be accessible. ```haskell C.context $ C.baseCtx <> mlirCtx C.include "mlir-c/IR.h" [C.exp| MlirType { mlirF32TypeGet($(MlirContext ctx)) } |] ``` -------------------------------- ### Convert AST Type to Native Type Source: https://github.com/google/mlir-hs/blob/main/_autodocs/README.md Illustrates converting an MLIR Abstract Syntax Tree (AST) type to its native representation using the `fromAST` function. Requires `MLIR.AST` and `MLIR.AST.Serialize`. The context and mapping dictionaries are passed as arguments. ```haskell import MLIR.AST import MLIR.AST.Serialize let astType = Float32Type nativeType <- fromAST ctx (mempty, mempty) astType ``` -------------------------------- ### Multiple MLIR Function Invocations Source: https://github.com/google/mlir-hs/blob/main/_autodocs/05-mlir-native-execution-engine.md Shows how to invoke multiple MLIR functions sequentially using the same execution engine, with different arguments and return types. Handles the results of all calls. ```haskell multipleInvokes :: ExecutionEngine -> IO () multipleInvokes eng = do r1 <- withStringRef "func1" \ref1 -> executionEngineInvoke eng ref1 [] r2 <- withStringRef "func2" \ref2 -> executionEngineInvoke eng ref2 [SomeStorable (5 :: Int)] r3 <- withStringRef "func3" \ref3 -> executionEngineInvoke eng ref3 [SomeStorable (2.5 :: Double)] case (r1, r2, r3) of (Just a, Just b, Just c) -> putStrLn $ "All succeeded: " ++ show (a, b, c) _ -> putStrLn "Some calls failed" ``` -------------------------------- ### ModuleOp Source: https://github.com/google/mlir-hs/blob/main/_autodocs/02-mlir-ast.md A pattern constructor for creating MLIR module operations. It takes a block representing the module's body. ```APIDOC ## ModuleOp ### Description Pattern constructor for creating MLIR module operations. ### Method N/A (Haskell pattern synonym) ### Signature ```haskell pattern ModuleOp :: Block -> Operation ``` ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```haskell let block = Block "0" [] [] modOp = ModuleOp block ``` ### Response #### Success Response MLIR Operation representing a module. #### Response Example N/A (Haskell data structure) ``` -------------------------------- ### Creating an Operation with Types Source: https://github.com/google/mlir-hs/blob/main/_autodocs/02-mlir-ast.md Demonstrates how to define an MLIR operation, specifically an 'arith.constant' operation, including its name, location, result types, and attributes. ```haskell let resultTypes = Explicit [Float32Type] op = Operation { opName = "arith.constant" , opLocation = UnknownLocation , opResultTypes = resultTypes , opOperands = [] , opRegions = [] , opSuccessors = [] , opAttributes = namedAttribute "value" (FloatAttr Float32Type 3.14) } ```