llvm-project
148 строк · 6.0 Кб
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 LLVM
4// Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10/* RUN: mlir-capi-execution-engine-test 2>&1 | FileCheck %s
11*/
12/* REQUIRES: host-supports-jit
13*/
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) {27MlirDialectRegistry registry = mlirDialectRegistryCreate();28mlirRegisterAllDialects(registry);29mlirContextAppendDialectRegistry(ctx, registry);30mlirDialectRegistryDestroy(registry);31}
32
33void lowerModuleToLLVM(MlirContext ctx, MlirModule module) {34MlirPassManager pm = mlirPassManagerCreate(ctx);35MlirOpPassManager opm = mlirPassManagerGetNestedUnder(36pm, mlirStringRefCreateFromCString("func.func"));37mlirPassManagerAddOwnedPass(pm, mlirCreateConversionConvertFuncToLLVMPass());38mlirOpPassManagerAddOwnedPass(39opm, mlirCreateConversionArithToLLVMConversionPass());40MlirLogicalResult status =41mlirPassManagerRunOnOp(pm, mlirModuleGetOperation(module));42if (mlirLogicalResultIsFailure(status)) {43fprintf(stderr, "Unexpected failure running pass pipeline\n");44exit(2);45}46mlirPassManagerDestroy(pm);47}
48
49// CHECK-LABEL: Running test 'testSimpleExecution'
50void testSimpleExecution(void) {51MlirContext ctx = mlirContextCreate();52registerAllUpstreamDialects(ctx);53
54MlirModule module = mlirModuleCreateParse(55ctx, mlirStringRefCreateFromCString(56// clang-format off57"module { \n"
58" func.func @add(%arg0 : i32) -> i32 attributes { llvm.emit_c_interface } { \n"
59" %res = arith.addi %arg0, %arg0 : i32 \n"
60" return %res : i32 \n"
61" } \n"
62"}"));63// clang-format on64lowerModuleToLLVM(ctx, module);65mlirRegisterAllLLVMTranslations(ctx);66MlirExecutionEngine jit = mlirExecutionEngineCreate(67module, /*optLevel=*/2, /*numPaths=*/0, /*sharedLibPaths=*/NULL,68/*enableObjectDump=*/false);69if (mlirExecutionEngineIsNull(jit)) {70fprintf(stderr, "Execution engine creation failed");71exit(2);72}73int input = 42;74int result = -1;75void *args[2] = {&input, &result};76if (mlirLogicalResultIsFailure(mlirExecutionEngineInvokePacked(77jit, mlirStringRefCreateFromCString("add"), args))) {78fprintf(stderr, "Execution engine creation failed");79abort();80}81// CHECK: Input: 42 Result: 8482printf("Input: %d Result: %d\n", input, result);83mlirExecutionEngineDestroy(jit);84mlirModuleDestroy(module);85mlirContextDestroy(ctx);86}
87
88// CHECK-LABEL: Running test 'testOmpCreation'
89void testOmpCreation(void) {90MlirContext ctx = mlirContextCreate();91registerAllUpstreamDialects(ctx);92
93MlirModule module = mlirModuleCreateParse(94ctx, mlirStringRefCreateFromCString(95// clang-format off96"module { \n"
97" func.func @main() attributes { llvm.emit_c_interface } { \n"
98" %0 = arith.constant 0 : i32 \n"
99" %1 = arith.constant 1 : i32 \n"
100" %2 = arith.constant 2 : i32 \n"
101" omp.parallel { \n"
102" omp.wsloop { \n"
103" omp.loop_nest (%3) : i32 = (%0) to (%2) step (%1) { \n"
104" omp.yield \n"
105" } \n"
106" omp.terminator \n"
107" } \n"
108" omp.terminator \n"
109" } \n"
110" llvm.return \n"
111" } \n"
112"} \n"
113));114// clang-format on115lowerModuleToLLVM(ctx, module);116
117// At this point all operations in the MLIR module have been lowered to the118// 'llvm' dialect except 'omp' operations. The goal of this test is119// guaranteeing that the execution engine C binding has registered OpenMP120// translations and therefore does not fail when it encounters 'omp' ops.121// We don't attempt to run the engine, since that would force us to link122// against the OpenMP library.123MlirExecutionEngine jit = mlirExecutionEngineCreate(124module, /*optLevel=*/2, /*numPaths=*/0, /*sharedLibPaths=*/NULL,125/*enableObjectDump=*/false);126if (mlirExecutionEngineIsNull(jit)) {127fprintf(stderr, "Engine creation failed with OpenMP");128exit(2);129}130// CHECK: Engine creation succeeded with OpenMP131printf("Engine creation succeeded with OpenMP\n");132mlirExecutionEngineDestroy(jit);133mlirModuleDestroy(module);134mlirContextDestroy(ctx);135}
136
137int main(void) {138
139#define _STRINGIFY(x) #x140#define STRINGIFY(x) _STRINGIFY(x)141#define TEST(test) \142printf("Running test '" STRINGIFY(test) "'\n"); \143test();144
145TEST(testSimpleExecution);146TEST(testOmpCreation);147return 0;148}
149