Skip to content
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

Add example of loading standalone dialect #49

Draft
wants to merge 1 commit into
base: vc/show
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions test/standalone/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
33 changes: 33 additions & 0 deletions test/standalone/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.13.4)
project(standalone-dialect LANGUAGES CXX C)

set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON)

set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to conform to")

find_package(MLIR REQUIRED CONFIG)

message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib)
set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR})

list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(TableGen)
include(AddLLVM)
include(AddMLIR)
include(HandleLLVMOptions)

include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${MLIR_INCLUDE_DIRS})
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_BINARY_DIR}/include)
link_directories(${LLVM_BUILD_LIBRARY_DIR})
add_definitions(${LLVM_DEFINITIONS})

add_subdirectory(include)
add_subdirectory(lib)
add_subdirectory(standalone-c)
6 changes: 6 additions & 0 deletions test/standalone/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[deps]
CMake_jll = "3f4e10e2-61f2-5801-8945-23b9d642d0e6"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
Scratch = "6c6a2e73-6563-6170-7368-637461726353"
18 changes: 18 additions & 0 deletions test/standalone/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# An out-of-tree MLIR dialect

This is an example of an out-of-tree [MLIR](https://mlir.llvm.org/) dialect along with a standalone `opt`-like tool to operate on that dialect.

## Building

This setup assumes that you have built LLVM and MLIR in `$BUILD_DIR` and installed them to `$PREFIX`. To build and launch the tests, run
```sh
mkdir build && cd build
cmake -G Ninja .. -DMLIR_DIR=$PREFIX/lib/cmake/mlir -DLLVM_EXTERNAL_LIT=$BUILD_DIR/bin/llvm-lit
cmake --build . --target check-standalone
```
To build the documentation from the TableGen description of the dialect operations, run
```sh
cmake --build . --target mlir-doc
```
**Note**: Make sure to pass `-DLLVM_INSTALL_UTILS=ON` when building LLVM with CMake in order to install `FileCheck` to the chosen installation prefix.

2 changes: 2 additions & 0 deletions test/standalone/Standalone/LocalPreferences.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Standalone]
libstandalone_c = "/home/vchuravy/.julia/scratchspaces/bfde9dd4-8f40-4a1e-be09-1475335e1c92/standalone/lib/libstandalone-c.so"
8 changes: 8 additions & 0 deletions test/standalone/Standalone/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name = "Standalone"
uuid = "581bf5d4-2b26-4c71-b8d4-1c51a2421152"
authors = ["Valentin Churavy <[email protected]>"]
version = "0.1.0"

[deps]
MLIR = "bfde9dd4-8f40-4a1e-be09-1475335e1c92"
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
24 changes: 24 additions & 0 deletions test/standalone/Standalone/src/Standalone.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Standalone

using MLIR
using Preferences

const libstandalone_c = @load_preference("libstandalone_c")

module StandaloneAPI
import ..Standalone: libstandalone_c
import MLIR.API: MlirDialectHandle
function mlirGetDialectHandle__standalone__()
@ccall libstandalone_c.mlirGetDialectHandle__standalone__()::MlirDialectHandle
end
end

import MLIR: API, IR, Dialects

function load_dialect(ctx)
dialect = IR.DialectHandle(StandaloneAPI.mlirGetDialectHandle__standalone__())
API.mlirDialectHandleRegisterDialect(dialect, ctx)
API.mlirDialectHandleLoadDialect(dialect, ctx)
end

end # module Standalone
9 changes: 9 additions & 0 deletions test/standalone/Standalone/test/runtests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Standalone
using MLIR

MLIR.IR.context!(MLIR.IR.Context()) do
for dialect in ("func", "cf")
MLIR.IR.get_or_load_dialect!(dialect)
end
Standalone.load_dialect(MLIR.IR.context())
end
85 changes: 85 additions & 0 deletions test/standalone/build_local.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using Pkg
Pkg.activate(@__DIR__)
Pkg.instantiate()

using Pkg, Scratch, Preferences, Libdl, CMake_jll

MLIR = Base.UUID("bfde9dd4-8f40-4a1e-be09-1475335e1c92")

# get scratch directories
scratch_dir = get_scratch!(MLIR, "standalone")
isdir(scratch_dir) && rm(scratch_dir; recursive=true)
source_dir = @__DIR__

# get build directory
build_dir = if isempty(ARGS)
mktempdir()
else
ARGS[1]
end
mkpath(build_dir)

# download LLVM
Pkg.activate(; temp=true)
llvm_assertions = try
cglobal((:_ZN4llvm24DisableABIBreakingChecksE, Base.libllvm_path()), Cvoid)
false
catch
true
end
llvm_pkg_version = "$(Base.libllvm_version.major).$(Base.libllvm_version.minor)"
LLVM = if llvm_assertions
Pkg.add(name="LLVM_full_assert_jll", version=llvm_pkg_version)
using LLVM_full_assert_jll
LLVM_full_assert_jll
else
Pkg.add(name="LLVM_full_jll", version=llvm_pkg_version)
using LLVM_full_jll
LLVM_full_jll
end
Pkg.add(name="mlir_jl_tblgen_jll")

LLVM_DIR = joinpath(LLVM.artifact_dir, "lib", "cmake", "llvm")
MLIR_DIR = joinpath(LLVM.artifact_dir, "lib", "cmake", "mlir")

# build and install
@info "Building" source_dir scratch_dir build_dir LLVM_DIR MLIR_DIR
cmake() do cmake_path
config_opts = `-DLLVM_ROOT=$(LLVM_DIR) -DMLIR_ROOT=$(MLIR_DIR) -DCMAKE_INSTALL_PREFIX=$(scratch_dir)`
if Sys.iswindows()
# prevent picking up MSVC
config_opts = `$config_opts -G "MSYS Makefiles"`
end
run(`$cmake_path $config_opts -B$(build_dir) -S$(source_dir)`)
run(`$cmake_path --build $(build_dir) --target install`)
end

# # discover built binaries
# built_libs = filter(readdir(joinpath(scratch_dir, "lib"))) do file
# endswith(file, "standalone.$(Libdl.dlext)")
# end

# libstandalone_path = joinpath(scratch_dir, "lib", only(built_libs))
# isfile(libstandalone_path) || error("Could not find library $libstandalone_path in build directory")

built_libs = filter(readdir(joinpath(scratch_dir, "lib"))) do file
endswith(file, "standalone-c.$(Libdl.dlext)")
end

libstandalone_c_path = joinpath(scratch_dir, "lib", only(built_libs))
isfile(libstandalone_c_path) || error("Could not find library $libstandalone_c_path in build directory")

# tell Standalone.jl to load our library instead of the default artifact one
set_preferences!(
joinpath(@__DIR__, "Standalone", "LocalPreferences.toml"),
"Standalone",
# "libstandalone" => libstandalone_path,
"libstandalone_c" => libstandalone_c_path;
force=true,
)

# include_dir = joinpath(LLVM.artifact_dir, "include")
# output = joinpath(@__DIR__, "Brutus", "src", "Dialects", string(Base.libllvm_version.major), "JuliaOps.jl")
# mkpath(dirname(output))
# using mlir_jl_tblgen_jll
# run(`$(mlir_jl_tblgen()) --generator=jl-op-defs include/brutus/Dialect/Julia/JuliaOps.td -Iinclude/ -I$include_dir -o $output`)
1 change: 1 addition & 0 deletions test/standalone/include/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(Standalone)
24 changes: 24 additions & 0 deletions test/standalone/include/Standalone-c/Dialects.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===- Dialects.h - CAPI for dialects -----------------------------*- C -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef STANDALONE_C_DIALECTS_H
#define STANDALONE_C_DIALECTS_H

#include "mlir-c/IR.h"

#ifdef __cplusplus
extern "C" {
#endif

MLIR_DECLARE_CAPI_DIALECT_REGISTRATION(Standalone, standalone);

#ifdef __cplusplus
}
#endif

#endif // STANDALONE_C_DIALECTS_H
3 changes: 3 additions & 0 deletions test/standalone/include/Standalone/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
add_mlir_dialect(StandaloneOps standalone)
add_mlir_doc(StandaloneDialect StandaloneDialect Standalone/ -gen-dialect-doc)
add_mlir_doc(StandaloneOps StandaloneOps Standalone/ -gen-op-doc)
16 changes: 16 additions & 0 deletions test/standalone/include/Standalone/StandaloneDialect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//===- StandaloneDialect.h - Standalone dialect -----------------*- C++ -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef STANDALONE_STANDALONEDIALECT_H
#define STANDALONE_STANDALONEDIALECT_H

#include "mlir/IR/Dialect.h"

#include "Standalone/StandaloneOpsDialect.h.inc"

#endif // STANDALONE_STANDALONEDIALECT_H
38 changes: 38 additions & 0 deletions test/standalone/include/Standalone/StandaloneDialect.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===- StandaloneDialect.td - Standalone dialect -----------*- tablegen -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef STANDALONE_DIALECT
#define STANDALONE_DIALECT

include "mlir/IR/OpBase.td"

//===----------------------------------------------------------------------===//
// Standalone dialect definition.
//===----------------------------------------------------------------------===//

def Standalone_Dialect : Dialect {
let name = "standalone";
let summary = "A standalone out-of-tree MLIR dialect.";
let description = [{
This dialect is an example of an out-of-tree MLIR dialect designed to
illustrate the basic setup required to develop MLIR-based tools without
working inside of the LLVM source tree.
}];
let cppNamespace = "::mlir::standalone";

let emitAccessorPrefix = kEmitAccessorPrefix_Prefixed;
}

//===----------------------------------------------------------------------===//
// Base standalone operation definition.
//===----------------------------------------------------------------------===//

class Standalone_Op<string mnemonic, list<Trait> traits = []> :
Op<Standalone_Dialect, mnemonic, traits>;

#endif // STANDALONE_DIALECT
21 changes: 21 additions & 0 deletions test/standalone/include/Standalone/StandaloneOps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===- StandaloneOps.h - Standalone dialect ops -----------------*- C++ -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef STANDALONE_STANDALONEOPS_H
#define STANDALONE_STANDALONEOPS_H

#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/Interfaces/InferTypeOpInterface.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"

#define GET_OP_CLASSES
#include "Standalone/StandaloneOps.h.inc"

#endif // STANDALONE_STANDALONEOPS_H
43 changes: 43 additions & 0 deletions test/standalone/include/Standalone/StandaloneOps.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//===- StandaloneOps.td - Standalone dialect ops -----------*- tablegen -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef STANDALONE_OPS
#define STANDALONE_OPS

include "Standalone/StandaloneDialect.td"
include "mlir/Interfaces/InferTypeOpInterface.td"
include "mlir/Interfaces/SideEffectInterfaces.td"

def Standalone_FooOp : Standalone_Op<"foo", [NoSideEffect,
SameOperandsAndResultType]> {
let summary = "Illustrates how to define an operation.";
let description = [{
The `standalone.foo` operation illustrates how to define a new
operation in a dialect. It uses an operation trait to declare that it
has no side effects.

This operation takes an integer argument and returns an integer.

Example:

```mlir
%0 = arith.constant 2 : i32
// Apply the foo operation to %0
%1 = standalone.foo %0 : i32
```
}];

let arguments = (ins I32:$input);
let results = (outs I32:$res);

let assemblyFormat = [{
$input attr-dict `:` type($input)
}];
}

#endif // STANDALONE_OPS
5 changes: 5 additions & 0 deletions test/standalone/lib/CAPI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
add_mlir_public_c_api_library(StandaloneCAPI
Dialects.cpp
LINK_LIBS PUBLIC
MLIRStandalone
)
15 changes: 15 additions & 0 deletions test/standalone/lib/CAPI/Dialects.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===- Dialects.cpp - CAPI for dialects -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Standalone-c/Dialects.h"

#include "Standalone/StandaloneDialect.h"
#include "mlir/CAPI/Registration.h"

MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(Standalone, standalone,
mlir::standalone::StandaloneDialect)
2 changes: 2 additions & 0 deletions test/standalone/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_subdirectory(CAPI)
add_subdirectory(Standalone)
14 changes: 14 additions & 0 deletions test/standalone/lib/Standalone/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_mlir_dialect_library(MLIRStandalone
StandaloneDialect.cpp
StandaloneOps.cpp

ADDITIONAL_HEADER_DIRS
${PROJECT_SOURCE_DIR}/include/Standalone

DEPENDS
MLIRStandaloneOpsIncGen

LINK_LIBS PUBLIC
MLIRIR
MLIRInferTypeOpInterface
)
Loading