186c8a785SMehdi Amini //===- execution_engine.c - Test for the C bindings for the MLIR JIT-------===// 286c8a785SMehdi Amini // 386c8a785SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM 486c8a785SMehdi Amini // Exceptions. 586c8a785SMehdi Amini // See https://llvm.org/LICENSE.txt for license information. 686c8a785SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 786c8a785SMehdi Amini // 886c8a785SMehdi Amini //===----------------------------------------------------------------------===// 986c8a785SMehdi Amini 1086c8a785SMehdi Amini /* RUN: mlir-capi-execution-engine-test 2>&1 | FileCheck %s 1186c8a785SMehdi Amini */ 12ca98e0ddSRainer Orth /* REQUIRES: host-supports-jit 135a68a85dSMehdi Amini */ 1486c8a785SMehdi Amini 1586c8a785SMehdi Amini #include "mlir-c/Conversion.h" 1686c8a785SMehdi Amini #include "mlir-c/ExecutionEngine.h" 1786c8a785SMehdi Amini #include "mlir-c/IR.h" 185e83a5b4SStella Laurenzo #include "mlir-c/RegisterEverything.h" 1986c8a785SMehdi Amini 2086c8a785SMehdi Amini #include <assert.h> 2186c8a785SMehdi Amini #include <math.h> 2286c8a785SMehdi Amini #include <stdio.h> 2386c8a785SMehdi Amini #include <stdlib.h> 2486c8a785SMehdi Amini #include <string.h> 2586c8a785SMehdi Amini 265e83a5b4SStella Laurenzo static void registerAllUpstreamDialects(MlirContext ctx) { 275e83a5b4SStella Laurenzo MlirDialectRegistry registry = mlirDialectRegistryCreate(); 285e83a5b4SStella Laurenzo mlirRegisterAllDialects(registry); 295e83a5b4SStella Laurenzo mlirContextAppendDialectRegistry(ctx, registry); 305e83a5b4SStella Laurenzo mlirDialectRegistryDestroy(registry); 315e83a5b4SStella Laurenzo } 325e83a5b4SStella Laurenzo 3386c8a785SMehdi Amini void lowerModuleToLLVM(MlirContext ctx, MlirModule module) { 3486c8a785SMehdi Amini MlirPassManager pm = mlirPassManagerCreate(ctx); 35a54f4eaeSMogball MlirOpPassManager opm = mlirPassManagerGetNestedUnder( 3636550692SRiver Riddle pm, mlirStringRefCreateFromCString("func.func")); 375dc34eb3STobias Gysi mlirPassManagerAddOwnedPass(pm, mlirCreateConversionConvertFuncToLLVMPass()); 38b1ce63bbSMichele Scuttari mlirOpPassManagerAddOwnedPass( 39abc362a1SJakub Kuderski opm, mlirCreateConversionArithToLLVMConversionPass()); 406f5590caSrkayaith MlirLogicalResult status = 416f5590caSrkayaith mlirPassManagerRunOnOp(pm, mlirModuleGetOperation(module)); 4286c8a785SMehdi Amini if (mlirLogicalResultIsFailure(status)) { 4386c8a785SMehdi Amini fprintf(stderr, "Unexpected failure running pass pipeline\n"); 4486c8a785SMehdi Amini exit(2); 4586c8a785SMehdi Amini } 4686c8a785SMehdi Amini mlirPassManagerDestroy(pm); 4786c8a785SMehdi Amini } 4886c8a785SMehdi Amini 4986c8a785SMehdi Amini // CHECK-LABEL: Running test 'testSimpleExecution' 505d91f79fSTom Eccles void testSimpleExecution(void) { 5186c8a785SMehdi Amini MlirContext ctx = mlirContextCreate(); 525e83a5b4SStella Laurenzo registerAllUpstreamDialects(ctx); 535e83a5b4SStella Laurenzo 5486c8a785SMehdi Amini MlirModule module = mlirModuleCreateParse( 5586c8a785SMehdi Amini ctx, mlirStringRefCreateFromCString( 5686c8a785SMehdi Amini // clang-format off 5786c8a785SMehdi Amini "module { \n" 58*0d9dc421SJonas Paulsson #ifdef __s390__ 59*0d9dc421SJonas Paulsson " func.func @add(%arg0 : i32) -> (i32 {llvm.signext}) attributes { llvm.emit_c_interface } { \n" 60*0d9dc421SJonas Paulsson #else 610fd3a1ceSRiver Riddle " func.func @add(%arg0 : i32) -> i32 attributes { llvm.emit_c_interface } { \n" 62*0d9dc421SJonas Paulsson #endif 63a54f4eaeSMogball " %res = arith.addi %arg0, %arg0 : i32 \n" 6486c8a785SMehdi Amini " return %res : i32 \n" 6586c8a785SMehdi Amini " } \n" 6686c8a785SMehdi Amini "}")); 6786c8a785SMehdi Amini // clang-format on 6886c8a785SMehdi Amini lowerModuleToLLVM(ctx, module); 6986c8a785SMehdi Amini mlirRegisterAllLLVMTranslations(ctx); 70c8b8e8e0SUday Bondhugula MlirExecutionEngine jit = mlirExecutionEngineCreate( 7195c083f5SDenys Shabalin module, /*optLevel=*/2, /*numPaths=*/0, /*sharedLibPaths=*/NULL, 7295c083f5SDenys Shabalin /*enableObjectDump=*/false); 7386c8a785SMehdi Amini if (mlirExecutionEngineIsNull(jit)) { 7486c8a785SMehdi Amini fprintf(stderr, "Execution engine creation failed"); 7586c8a785SMehdi Amini exit(2); 7686c8a785SMehdi Amini } 7786c8a785SMehdi Amini int input = 42; 7886c8a785SMehdi Amini int result = -1; 7986c8a785SMehdi Amini void *args[2] = {&input, &result}; 8086c8a785SMehdi Amini if (mlirLogicalResultIsFailure(mlirExecutionEngineInvokePacked( 8186c8a785SMehdi Amini jit, mlirStringRefCreateFromCString("add"), args))) { 8286c8a785SMehdi Amini fprintf(stderr, "Execution engine creation failed"); 8386c8a785SMehdi Amini abort(); 8486c8a785SMehdi Amini } 8586c8a785SMehdi Amini // CHECK: Input: 42 Result: 84 8686c8a785SMehdi Amini printf("Input: %d Result: %d\n", input, result); 8786c8a785SMehdi Amini mlirExecutionEngineDestroy(jit); 8886c8a785SMehdi Amini mlirModuleDestroy(module); 8986c8a785SMehdi Amini mlirContextDestroy(ctx); 9086c8a785SMehdi Amini } 9186c8a785SMehdi Amini 92db7cc034SRafael Ubal Tena // CHECK-LABEL: Running test 'testOmpCreation' 93db7cc034SRafael Ubal Tena void testOmpCreation(void) { 94db7cc034SRafael Ubal Tena MlirContext ctx = mlirContextCreate(); 95db7cc034SRafael Ubal Tena registerAllUpstreamDialects(ctx); 96db7cc034SRafael Ubal Tena 97db7cc034SRafael Ubal Tena MlirModule module = mlirModuleCreateParse( 98db7cc034SRafael Ubal Tena ctx, mlirStringRefCreateFromCString( 99db7cc034SRafael Ubal Tena // clang-format off 100db7cc034SRafael Ubal Tena "module { \n" 101db7cc034SRafael Ubal Tena " func.func @main() attributes { llvm.emit_c_interface } { \n" 102db7cc034SRafael Ubal Tena " %0 = arith.constant 0 : i32 \n" 103db7cc034SRafael Ubal Tena " %1 = arith.constant 1 : i32 \n" 104db7cc034SRafael Ubal Tena " %2 = arith.constant 2 : i32 \n" 105db7cc034SRafael Ubal Tena " omp.parallel { \n" 10607e6c160SSergio Afonso " omp.wsloop { \n" 10707e6c160SSergio Afonso " omp.loop_nest (%3) : i32 = (%0) to (%2) step (%1) { \n" 108db7cc034SRafael Ubal Tena " omp.yield \n" 109db7cc034SRafael Ubal Tena " } \n" 110db7cc034SRafael Ubal Tena " } \n" 11107e6c160SSergio Afonso " omp.terminator \n" 11207e6c160SSergio Afonso " } \n" 113db7cc034SRafael Ubal Tena " llvm.return \n" 114db7cc034SRafael Ubal Tena " } \n" 115db7cc034SRafael Ubal Tena "} \n" 116db7cc034SRafael Ubal Tena )); 117db7cc034SRafael Ubal Tena // clang-format on 118db7cc034SRafael Ubal Tena lowerModuleToLLVM(ctx, module); 119db7cc034SRafael Ubal Tena 120db7cc034SRafael Ubal Tena // At this point all operations in the MLIR module have been lowered to the 121db7cc034SRafael Ubal Tena // 'llvm' dialect except 'omp' operations. The goal of this test is 122db7cc034SRafael Ubal Tena // guaranteeing that the execution engine C binding has registered OpenMP 123db7cc034SRafael Ubal Tena // translations and therefore does not fail when it encounters 'omp' ops. 124db7cc034SRafael Ubal Tena // We don't attempt to run the engine, since that would force us to link 125db7cc034SRafael Ubal Tena // against the OpenMP library. 126db7cc034SRafael Ubal Tena MlirExecutionEngine jit = mlirExecutionEngineCreate( 127db7cc034SRafael Ubal Tena module, /*optLevel=*/2, /*numPaths=*/0, /*sharedLibPaths=*/NULL, 128db7cc034SRafael Ubal Tena /*enableObjectDump=*/false); 129db7cc034SRafael Ubal Tena if (mlirExecutionEngineIsNull(jit)) { 130db7cc034SRafael Ubal Tena fprintf(stderr, "Engine creation failed with OpenMP"); 131db7cc034SRafael Ubal Tena exit(2); 132db7cc034SRafael Ubal Tena } 133db7cc034SRafael Ubal Tena // CHECK: Engine creation succeeded with OpenMP 134db7cc034SRafael Ubal Tena printf("Engine creation succeeded with OpenMP\n"); 135db7cc034SRafael Ubal Tena mlirExecutionEngineDestroy(jit); 136db7cc034SRafael Ubal Tena mlirModuleDestroy(module); 137db7cc034SRafael Ubal Tena mlirContextDestroy(ctx); 138db7cc034SRafael Ubal Tena } 139db7cc034SRafael Ubal Tena 1405d91f79fSTom Eccles int main(void) { 14186c8a785SMehdi Amini 14286c8a785SMehdi Amini #define _STRINGIFY(x) #x 14386c8a785SMehdi Amini #define STRINGIFY(x) _STRINGIFY(x) 14486c8a785SMehdi Amini #define TEST(test) \ 14586c8a785SMehdi Amini printf("Running test '" STRINGIFY(test) "'\n"); \ 14686c8a785SMehdi Amini test(); 14786c8a785SMehdi Amini 14886c8a785SMehdi Amini TEST(testSimpleExecution); 149db7cc034SRafael Ubal Tena TEST(testOmpCreation); 15086c8a785SMehdi Amini return 0; 15186c8a785SMehdi Amini } 152