Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add C bindings for mlir::ExecutionEngine
This adds minimalistic bindings for the execution engine, allowing to invoke the JIT from the C API. This is still quite early and experimental and shouldn't be considered stable in any way. Differential Revision: https://reviews.llvm.org/D96651
- Loading branch information
Showing
14 changed files
with
304 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//===-- mlir-c/Conversion.h - Conversion passes initialization ----*- C -*-===// | ||
// | ||
// 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This header declares the registration and creation method for conversion | ||
// passes. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef MLIR_C_CONVERSIONS_H | ||
#define MLIR_C_CONVERSIONS_H | ||
|
||
#include "mlir-c/Support.h" | ||
|
||
#include "mlir/Conversion/Passes.capi.h.inc" | ||
|
||
#endif // MLIR_C_CONVERSIONS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
//===-- mlir-c/ExecutionEngine.h - Execution engine management ---*- C -*-====// | ||
// | ||
// 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This header provides basic access to the MLIR JIT. This is minimalist and | ||
// experimental at the moment. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef MLIR_C_EXECUTIONENGINE_H | ||
#define MLIR_C_EXECUTIONENGINE_H | ||
|
||
#include "mlir-c/IR.h" | ||
#include "mlir-c/Support.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#define DEFINE_C_API_STRUCT(name, storage) \ | ||
struct name { \ | ||
storage *ptr; \ | ||
}; \ | ||
typedef struct name name | ||
|
||
DEFINE_C_API_STRUCT(MlirExecutionEngine, void); | ||
|
||
#undef DEFINE_C_API_STRUCT | ||
|
||
/// Creates an ExecutionEngine for the provided ModuleOp. The ModuleOp is | ||
/// expected to be "translatable" to LLVM IR (only contains operations in | ||
/// dialects that implement the `LLVMTranslationDialectInterface`). The module | ||
/// ownership stays with the client and can be destroyed as soon as the call | ||
/// returns. | ||
/// TODO: figure out options (optimization level, etc.). | ||
MLIR_CAPI_EXPORTED MlirExecutionEngine mlirExecutionEngineCreate(MlirModule op); | ||
|
||
/// Destroy an ExecutionEngine instance. | ||
MLIR_CAPI_EXPORTED void mlirExecutionEngineDestroy(MlirExecutionEngine jit); | ||
|
||
/// Checks whether an execution engine is null. | ||
static inline bool mlirExecutionEngineIsNull(MlirExecutionEngine jit) { | ||
return !jit.ptr; | ||
} | ||
|
||
/// Invoke a native function in the execution engine by name with the arguments | ||
/// and result of the invoked function passed as an array of pointers. The | ||
/// function must have been tagged with the `llvm.emit_c_interface` attribute. | ||
/// Returns a failure if the execution fails for any reason (the function name | ||
/// can't be resolved for instance). | ||
MLIR_CAPI_EXPORTED MlirLogicalResult mlirExecutionEngineInvokePacked( | ||
MlirExecutionEngine jit, MlirStringRef name, void **arguments); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif // EXECUTIONENGINE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//===- IR.h - C API Utils for Core MLIR classes -----------------*- C++ -*-===// | ||
// | ||
// 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file contains declarations of implementation details of the C API for | ||
// core MLIR classes. This file should not be included from C++ code other than | ||
// C API implementation nor from C code. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef MLIR_CAPI_EXECUTIONENGINE_H | ||
#define MLIR_CAPI_EXECUTIONENGINE_H | ||
|
||
#include "mlir-c/ExecutionEngine.h" | ||
#include "mlir/CAPI/Wrap.h" | ||
#include "mlir/ExecutionEngine/ExecutionEngine.h" | ||
|
||
DEFINE_C_API_PTR_METHODS(MlirExecutionEngine, mlir::ExecutionEngine) | ||
|
||
#endif // MLIR_CAPI_EXECUTIONENGINE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
|
||
set(LLVM_TARGET_DEFINITIONS Passes.td) | ||
mlir_tablegen(Passes.h.inc -gen-pass-decls -name Conversion) | ||
mlir_tablegen(Passes.capi.h.inc -gen-pass-capi-header --prefix Conversion) | ||
mlir_tablegen(Passes.capi.cpp.inc -gen-pass-capi-impl --prefix Conversion) | ||
add_public_tablegen_target(MLIRConversionPassIncGen) | ||
|
||
add_mlir_doc(Passes -gen-pass-doc ConversionPasses ./) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS) | ||
add_mlir_public_c_api_library(MLIRCAPIConversion | ||
Passes.cpp | ||
|
||
LINK_LIBS PUBLIC | ||
${conversion_libs} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
//===- Conversion.cpp - C API for Conversion Passes -----------------------===// | ||
// | ||
// 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 "mlir/Conversion/Passes.h" | ||
#include "mlir/CAPI/Pass.h" | ||
#include "mlir/Pass/Pass.h" | ||
|
||
// Must include the declarations as they carry important visibility attributes. | ||
#include "mlir/Conversion/Passes.capi.h.inc" | ||
|
||
using namespace mlir; | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include "mlir/Conversion/Passes.capi.cpp.inc" | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Main API shared library. | ||
add_mlir_public_c_api_library(MLIRCEXECUTIONENGINE | ||
ExecutionEngine.cpp | ||
|
||
LINK_LIBS PUBLIC | ||
MLIRExecutionEngine | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
//===- ExecutionEngine.cpp - C API for MLIR JIT ---------------------------===// | ||
// | ||
// 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 "mlir-c/ExecutionEngine.h" | ||
#include "mlir/CAPI/ExecutionEngine.h" | ||
#include "mlir/CAPI/IR.h" | ||
#include "mlir/CAPI/Support.h" | ||
#include "llvm/Support/TargetSelect.h" | ||
|
||
using namespace mlir; | ||
|
||
extern "C" MlirExecutionEngine mlirExecutionEngineCreate(MlirModule op) { | ||
static bool init_once = [] { | ||
llvm::InitializeNativeTarget(); | ||
llvm::InitializeNativeTargetAsmPrinter(); | ||
return true; | ||
}(); | ||
(void)init_once; | ||
|
||
auto jitOrError = ExecutionEngine::create(unwrap(op)); | ||
if (!jitOrError) { | ||
consumeError(jitOrError.takeError()); | ||
return MlirExecutionEngine{nullptr}; | ||
} | ||
return wrap(jitOrError->release()); | ||
} | ||
|
||
extern "C" void mlirExecutionEngineDestroy(MlirExecutionEngine jit) { | ||
delete (unwrap(jit)); | ||
} | ||
|
||
extern "C" MlirLogicalResult | ||
mlirExecutionEngineInvokePacked(MlirExecutionEngine jit, MlirStringRef name, | ||
void **arguments) { | ||
const std::string ifaceName = ("_mlir_ciface_" + unwrap(name)).str(); | ||
llvm::Error error = unwrap(jit)->invokePacked( | ||
ifaceName, MutableArrayRef<void *>{arguments, (size_t)0}); | ||
if (error) | ||
return wrap(failure()); | ||
return wrap(success()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
//===- execution_engine.c - Test for the C bindings for the MLIR JIT-------===// | ||
// | ||
// 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
/* RUN: mlir-capi-execution-engine-test 2>&1 | FileCheck %s | ||
*/ | ||
|
||
#include "mlir-c/Conversion.h" | ||
#include "mlir-c/ExecutionEngine.h" | ||
#include "mlir-c/IR.h" | ||
#include "mlir-c/Registration.h" | ||
|
||
#include <assert.h> | ||
#include <math.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
void lowerModuleToLLVM(MlirContext ctx, MlirModule module) { | ||
MlirPassManager pm = mlirPassManagerCreate(ctx); | ||
mlirPassManagerAddOwnedPass(pm, mlirCreateConversionConvertStandardToLLVM()); | ||
MlirLogicalResult status = mlirPassManagerRun(pm, module); | ||
if (mlirLogicalResultIsFailure(status)) { | ||
fprintf(stderr, "Unexpected failure running pass pipeline\n"); | ||
exit(2); | ||
} | ||
mlirPassManagerDestroy(pm); | ||
} | ||
|
||
// CHECK-LABEL: Running test 'testSimpleExecution' | ||
void testSimpleExecution() { | ||
MlirContext ctx = mlirContextCreate(); | ||
mlirRegisterAllDialects(ctx); | ||
MlirModule module = mlirModuleCreateParse( | ||
ctx, mlirStringRefCreateFromCString( | ||
// clang-format off | ||
"module { \n" | ||
" func @add(%arg0 : i32) -> i32 attributes { llvm.emit_c_interface } { \n" | ||
" %res = std.addi %arg0, %arg0 : i32 \n" | ||
" return %res : i32 \n" | ||
" } \n" | ||
"}")); | ||
// clang-format on | ||
lowerModuleToLLVM(ctx, module); | ||
mlirRegisterAllLLVMTranslations(ctx); | ||
MlirExecutionEngine jit = mlirExecutionEngineCreate(module); | ||
if (mlirExecutionEngineIsNull(jit)) { | ||
fprintf(stderr, "Execution engine creation failed"); | ||
exit(2); | ||
} | ||
int input = 42; | ||
int result = -1; | ||
void *args[2] = {&input, &result}; | ||
if (mlirLogicalResultIsFailure(mlirExecutionEngineInvokePacked( | ||
jit, mlirStringRefCreateFromCString("add"), args))) { | ||
fprintf(stderr, "Execution engine creation failed"); | ||
abort(); | ||
} | ||
// CHECK: Input: 42 Result: 84 | ||
printf("Input: %d Result: %d\n", input, result); | ||
mlirExecutionEngineDestroy(jit); | ||
mlirModuleDestroy(module); | ||
mlirContextDestroy(ctx); | ||
} | ||
|
||
int main() { | ||
|
||
#define _STRINGIFY(x) #x | ||
#define STRINGIFY(x) _STRINGIFY(x) | ||
#define TEST(test) \ | ||
printf("Running test '" STRINGIFY(test) "'\n"); \ | ||
test(); | ||
|
||
TEST(testSimpleExecution); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters