152 lines · c
1//===- execution_engine.c - Test for the C bindings for the MLIR JIT-------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM4// Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10/* RUN: mlir-capi-execution-engine-test 2>&1 | FileCheck %s11 */12/* REQUIRES: host-supports-jit13 */14 15#include "mlir-c/Conversion.h"16#include "mlir-c/ExecutionEngine.h"17#include "mlir-c/IR.h"18#include "mlir-c/RegisterEverything.h"19 20#include <assert.h>21#include <math.h>22#include <stdio.h>23#include <stdlib.h>24#include <string.h>25 26static void registerAllUpstreamDialects(MlirContext ctx) {27 MlirDialectRegistry registry = mlirDialectRegistryCreate();28 mlirRegisterAllDialects(registry);29 mlirContextAppendDialectRegistry(ctx, registry);30 mlirDialectRegistryDestroy(registry);31}32 33void lowerModuleToLLVM(MlirContext ctx, MlirModule module) {34 MlirPassManager pm = mlirPassManagerCreate(ctx);35 MlirOpPassManager opm = mlirPassManagerGetNestedUnder(36 pm, mlirStringRefCreateFromCString("func.func"));37 mlirPassManagerAddOwnedPass(pm, mlirCreateConversionConvertFuncToLLVMPass());38 mlirOpPassManagerAddOwnedPass(39 opm, mlirCreateConversionArithToLLVMConversionPass());40 MlirLogicalResult status =41 mlirPassManagerRunOnOp(pm, mlirModuleGetOperation(module));42 if (mlirLogicalResultIsFailure(status)) {43 fprintf(stderr, "Unexpected failure running pass pipeline\n");44 exit(2);45 }46 mlirPassManagerDestroy(pm);47}48 49// CHECK-LABEL: Running test 'testSimpleExecution'50void testSimpleExecution(void) {51 MlirContext ctx = mlirContextCreate();52 registerAllUpstreamDialects(ctx);53 54 MlirModule module = mlirModuleCreateParse(55 ctx, mlirStringRefCreateFromCString(56 // clang-format off57"module { \n"58#ifdef __s390__59" func.func @add(%arg0 : i32) -> (i32 {llvm.signext}) attributes { llvm.emit_c_interface } { \n"60#else61" func.func @add(%arg0 : i32) -> i32 attributes { llvm.emit_c_interface } { \n"62#endif63" %res = arith.addi %arg0, %arg0 : i32 \n"64" return %res : i32 \n"65" } \n"66"}"));67 // clang-format on68 lowerModuleToLLVM(ctx, module);69 mlirRegisterAllLLVMTranslations(ctx);70 MlirExecutionEngine jit = mlirExecutionEngineCreate(71 module, /*optLevel=*/2, /*numPaths=*/0, /*sharedLibPaths=*/NULL,72 /*enableObjectDump=*/false);73 if (mlirExecutionEngineIsNull(jit)) {74 fprintf(stderr, "Execution engine creation failed");75 exit(2);76 }77 int input = 42;78 int result = -1;79 void *args[2] = {&input, &result};80 if (mlirLogicalResultIsFailure(mlirExecutionEngineInvokePacked(81 jit, mlirStringRefCreateFromCString("add"), args))) {82 fprintf(stderr, "Execution engine creation failed");83 abort();84 }85 // CHECK: Input: 42 Result: 8486 printf("Input: %d Result: %d\n", input, result);87 mlirExecutionEngineDestroy(jit);88 mlirModuleDestroy(module);89 mlirContextDestroy(ctx);90}91 92// CHECK-LABEL: Running test 'testOmpCreation'93void testOmpCreation(void) {94 MlirContext ctx = mlirContextCreate();95 registerAllUpstreamDialects(ctx);96 97 MlirModule module = mlirModuleCreateParse(98 ctx, mlirStringRefCreateFromCString(99 // clang-format off100"module { \n"101" func.func @main() attributes { llvm.emit_c_interface } { \n"102" %0 = arith.constant 0 : i32 \n"103" %1 = arith.constant 1 : i32 \n"104" %2 = arith.constant 2 : i32 \n"105" omp.parallel { \n"106" omp.wsloop { \n"107" omp.loop_nest (%3) : i32 = (%0) to (%2) step (%1) { \n"108" omp.yield \n"109" } \n"110" } \n"111" omp.terminator \n"112" } \n"113" llvm.return \n"114" } \n"115"} \n"116 ));117 // clang-format on118 lowerModuleToLLVM(ctx, module);119 120 // At this point all operations in the MLIR module have been lowered to the121 // 'llvm' dialect except 'omp' operations. The goal of this test is122 // guaranteeing that the execution engine C binding has registered OpenMP123 // translations and therefore does not fail when it encounters 'omp' ops.124 // We don't attempt to run the engine, since that would force us to link125 // against the OpenMP library.126 MlirExecutionEngine jit = mlirExecutionEngineCreate(127 module, /*optLevel=*/2, /*numPaths=*/0, /*sharedLibPaths=*/NULL,128 /*enableObjectDump=*/false);129 if (mlirExecutionEngineIsNull(jit)) {130 fprintf(stderr, "Engine creation failed with OpenMP");131 exit(2);132 }133 // CHECK: Engine creation succeeded with OpenMP134 printf("Engine creation succeeded with OpenMP\n");135 mlirExecutionEngineDestroy(jit);136 mlirModuleDestroy(module);137 mlirContextDestroy(ctx);138}139 140int main(void) {141 142#define _STRINGIFY(x) #x143#define STRINGIFY(x) _STRINGIFY(x)144#define TEST(test) \145 printf("Running test '" STRINGIFY(test) "'\n"); \146 test();147 148 TEST(testSimpleExecution);149 TEST(testOmpCreation);150 return 0;151}152