Skip to content

Commit 7f4f529

Browse files
Implemented GPU runner
1 parent 3e2e587 commit 7f4f529

File tree

12 files changed

+271
-44
lines changed

12 files changed

+271
-44
lines changed

cmake/functions.cmake

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,36 @@ function(gc_add_mlir_dialect_library name)
117117
if(GcInterface IN_LIST ARGN)
118118
target_link_libraries(obj.${name} PUBLIC GcInterface)
119119
endif()
120-
endfunction()
120+
endfunction()
121+
122+
macro(gc_add_mlir_tool name)
123+
# the dependency list copied from mlir/tools/mlir-cpu-runner/CMakeLists.txt of upstream
124+
if(NOT DEFINED LLVM_LINK_COMPONENTS)
125+
set(LLVM_LINK_COMPONENTS
126+
Core
127+
Support
128+
nativecodegen
129+
native
130+
)
131+
endif()
132+
if(NOT DEFINED MLIR_LINK_COMPONENTS)
133+
gc_set_mlir_link_components(MLIR_LINK_COMPONENTS
134+
MLIRAnalysis
135+
MLIRBuiltinToLLVMIRTranslation
136+
MLIRExecutionEngine
137+
MLIRIR
138+
MLIRJitRunner
139+
MLIRLLVMDialect
140+
MLIRLLVMToLLVMIRTranslation
141+
MLIRToLLVMIRTranslationRegistration
142+
MLIRParser
143+
MLIRTargetLLVMIRExport
144+
MLIRSupport
145+
)
146+
endif()
147+
add_mlir_tool(${ARGV})
148+
#LLVM_LINK_COMPONENTS is processed by LLVM cmake in add_llvm_executable
149+
target_link_libraries(${name} PRIVATE GcInterface ${MLIR_LINK_COMPONENTS})
150+
llvm_update_compile_flags(${name})
151+
set_property(GLOBAL APPEND PROPERTY GC_TOOLS ${name})
152+
endmacro()

lib/gc/ExecutionEngine/GPURuntime/ocl/GpuOclRuntime.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,7 @@ OclModuleBuilder::build(const OclRuntime::Ext &ext) {
804804
ExecutionEngineOptions opts;
805805
opts.jitCodeGenOptLevel = llvm::CodeGenOptLevel::Aggressive;
806806
opts.enableObjectDump = enableObjectDump;
807+
opts.sharedLibPaths = sharedLibPaths;
807808
#ifdef NDEBUG
808809
opts.enableGDBNotificationListener = false;
809810
opts.enablePerfNotificationListener = false;

src/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
################################################################################
2+
# Copyright (C) 2024 Intel Corporation
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing,
11+
# software distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions
14+
# and limitations under the License.
15+
# SPDX-License-Identifier: Apache-2.0
16+
################################################################################
17+
118
add_subdirectory(dnnl)
219
add_subdirectory(gc-cpu-runner)
20+
add_subdirectory(gc-gpu-runner)
321
add_subdirectory(gc-opt)

src/gc-cpu-runner/CMakeLists.txt

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,38 +29,8 @@ if(GC_DEV_LINK_LLVM_DYLIB)
2929
MLIRExecutionEngineShared
3030
MLIRJitRunner
3131
)
32-
else()
33-
# the dependency list copied from mlir/tools/mlir-cpu-runner/CMakeLists.txt of upstream
34-
set(LLVM_LINK_COMPONENTS
35-
Core
36-
Support
37-
nativecodegen
38-
native
39-
)
40-
set(MLIR_LINK_COMPONENTS
41-
MLIRAnalysis
42-
MLIRBuiltinToLLVMIRTranslation
43-
MLIRExecutionEngine
44-
MLIRIR
45-
MLIRJitRunner
46-
MLIRLLVMDialect
47-
MLIRLLVMToLLVMIRTranslation
48-
MLIRToLLVMIRTranslationRegistration
49-
MLIRParser
50-
MLIRTargetLLVMIRExport
51-
MLIRSupport
52-
)
5332
endif()
5433

55-
#LLVM_LINK_COMPONENTS is processed by LLVM cmake in add_llvm_executable
56-
set(gc_cpu_runner_libs
57-
${MLIR_LINK_COMPONENTS}
58-
GcCpuRuntime)
59-
add_mlir_tool(gc-cpu-runner
60-
gc-cpu-runner.cpp
61-
62-
)
63-
llvm_update_compile_flags(gc-cpu-runner)
64-
65-
target_link_libraries(gc-cpu-runner PRIVATE GcInterface ${gc_cpu_runner_libs})
34+
gc_add_mlir_tool(gc-cpu-runner gc-cpu-runner.cpp)
35+
target_link_libraries(gc-cpu-runner PRIVATE GcCpuRuntime)
6636
mlir_check_all_link_libraries(gc-cpu-runner)

src/gc-gpu-runner/CMakeLists.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
################################################################################
2+
# Copyright (C) 2024 Intel Corporation
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing,
11+
# software distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions
14+
# and limitations under the License.
15+
# SPDX-License-Identifier: Apache-2.0
16+
################################################################################
17+
18+
if(NOT GC_ENABLE_TOOLS OR NOT GC_ENABLE_IMEX)
19+
message(STATUS "Gpu runner is not enabled.")
20+
return()
21+
endif()
22+
23+
gc_add_mlir_tool(gc-gpu-runner GpuRunner.cpp)
24+
target_link_libraries(gc-gpu-runner PRIVATE
25+
GcJitWrapper
26+
GcGpuOclRuntime
27+
)
28+
mlir_check_all_link_libraries(gc-gpu-runner)

src/gc-gpu-runner/GpuRunner.cpp

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* Copyright (C) 2024 Intel Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing,
11+
* software distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions
14+
* and limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
*/
18+
19+
#include "gc/ExecutionEngine/Driver/Driver.h"
20+
#include "gc/ExecutionEngine/GPURuntime/GpuOclRuntime.h"
21+
#include "gc/Transforms/Passes.h"
22+
#include "gc/Utils/Error.h"
23+
24+
#include "mlir/Dialect/Arith/IR/Arith.h"
25+
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
26+
#include "mlir/ExecutionEngine/JitRunner.h"
27+
#include "mlir/ExecutionEngine/OptUtils.h"
28+
#include "mlir/IR/MLIRContext.h"
29+
#include "mlir/Support/FileUtilities.h"
30+
#include "mlir/Tools/ParseUtilities.h"
31+
#include "mlir/Transforms/Passes.h"
32+
33+
#include "llvm/Support/CommandLine.h"
34+
#include "llvm/Support/InitLLVM.h"
35+
#include "llvm/Support/SourceMgr.h"
36+
37+
using namespace mlir;
38+
39+
namespace {
40+
struct Options {
41+
llvm::cl::OptionCategory runnerCategory{"GPU runner options"};
42+
llvm::cl::opt<std::string> inputFilename{
43+
llvm::cl::Positional, llvm::cl::desc("<input file>"), llvm::cl::init("-"),
44+
llvm::cl::cat(runnerCategory)};
45+
llvm::cl::opt<std::string> mainFuncName{
46+
"e",
47+
llvm::cl::desc("The function to be executed. If not specified, the "
48+
"first matching function in the module to be used."),
49+
llvm::cl::value_desc("function name"), llvm::cl::cat(runnerCategory)};
50+
llvm::cl::opt<bool> skipPipeline{
51+
"skip-pipeline",
52+
llvm::cl::desc("Skip the GPU pipeline. It's expected, that the input is "
53+
"already lowered with 'gc-op --gc-gpu-pipeline'."),
54+
llvm::cl::init(false), llvm::cl::cat(runnerCategory)};
55+
llvm::cl::list<std::string> sharedLibs{
56+
"shared-libs",
57+
llvm::cl::desc("Comma separated library paths to link dynamically."),
58+
llvm::cl::MiscFlags::CommaSeparated, llvm::cl::desc("<lib1,lib2,...>"),
59+
llvm::cl::cat(runnerCategory)};
60+
llvm::cl::opt<bool> printIr{
61+
"print-ir", llvm::cl::desc("Print the IR before the execution."),
62+
llvm::cl::init(false), llvm::cl::cat(runnerCategory)};
63+
llvm::cl::opt<std::string> objDumpFile{
64+
"obj-dump-file",
65+
llvm::cl::desc("Dump the compiled object to the specified file."),
66+
llvm::cl::value_desc("file path"), llvm::cl::cat(runnerCategory)};
67+
};
68+
} // namespace
69+
70+
void findFunc(Options &opts, ModuleOp mod) {
71+
bool (*matcher)(ArrayRef<Type>, ModuleOp &);
72+
73+
if (opts.skipPipeline) {
74+
matcher = [](ArrayRef<Type> args, ModuleOp &mod) {
75+
if (args.size() != 3)
76+
return false;
77+
auto ctx = mod.getContext();
78+
auto ptrType = LLVM::LLVMPointerType::get(ctx);
79+
return args[0] == ptrType && args[1] == ptrType &&
80+
args[2] == IntegerType::get(ctx, 64);
81+
};
82+
} else {
83+
matcher = [](ArrayRef<Type> args, ModuleOp &) { return args.empty(); };
84+
}
85+
86+
if (opts.mainFuncName.empty()) {
87+
auto setFuncName = [&](auto funcOp) {
88+
if (funcOp && !funcOp.isExternal() && funcOp.isPublic() &&
89+
matcher(funcOp.getArgumentTypes(), mod)) {
90+
opts.mainFuncName = funcOp.getName().str();
91+
return true;
92+
}
93+
return false;
94+
};
95+
96+
for (auto &op : mod.getBody()->getOperations()) {
97+
if (setFuncName(dyn_cast<LLVM::LLVMFuncOp>(op)) ||
98+
setFuncName(dyn_cast<func::FuncOp>(op))) {
99+
return;
100+
}
101+
}
102+
gcReportErr("No matching function found.");
103+
}
104+
105+
ArrayRef<Type> args;
106+
if (auto llvmFunc = mod.lookupSymbol<LLVM::LLVMFuncOp>(opts.mainFuncName)) {
107+
args = llvmFunc.getArgumentTypes();
108+
} else if (auto func = mod.lookupSymbol<func::FuncOp>(opts.mainFuncName)) {
109+
args = func.getArgumentTypes();
110+
} else {
111+
gcReportErr("The function '", opts.mainFuncName.c_str(), "' not found.");
112+
}
113+
114+
if (!matcher(args, mod)) {
115+
if (opts.skipPipeline) {
116+
gcReportErr("The function '", opts.mainFuncName.c_str(),
117+
"' signature does not match (!llvm.ptr, !llvm.ptr, i64).");
118+
}
119+
gcReportErr("The function '", opts.mainFuncName.c_str(),
120+
"' must have no arguments.");
121+
}
122+
}
123+
124+
void pipeline(OpPassManager &pm) {
125+
gc::GPUPipelineOption pipelineOpts;
126+
pipelineOpts.isUsmArgs = false;
127+
pipelineOpts.callFinish = true;
128+
populateGPUPipeline(pm, pipelineOpts);
129+
}
130+
131+
int main(int argc, char **argv) {
132+
Options opts;
133+
llvm::cl::ParseCommandLineOptions(argc, argv, "GraphCompiler GPU runner\n");
134+
135+
std::string errMsg;
136+
auto file = openInputFile(opts.inputFilename, &errMsg);
137+
if (!file) {
138+
gcReportErr("Failed to read input IR: ", errMsg.c_str());
139+
}
140+
141+
auto srcMgr = std::make_shared<llvm::SourceMgr>();
142+
srcMgr->AddNewSourceBuffer(std::move(file), SMLoc());
143+
MLIRContext mlirCtx{gc::initCompilerAndGetDialects()};
144+
auto mlirMod = parseSourceFile<ModuleOp>(srcMgr, {&mlirCtx});
145+
findFunc(opts, *mlirMod);
146+
147+
gc::gpu::OclModuleBuilderOpts builderOpts;
148+
SmallVector<StringRef, 4> sharedLibs(opts.sharedLibs.begin(),
149+
opts.sharedLibs.end());
150+
builderOpts.funcName = opts.mainFuncName;
151+
builderOpts.enableObjectDump = !opts.objDumpFile.getValue().empty();
152+
builderOpts.sharedLibPaths = sharedLibs;
153+
if (opts.skipPipeline) {
154+
builderOpts.pipeline =
155+
opts.printIr
156+
? [](OpPassManager &pm) { pm.addPass(createPrintIRPass()); }
157+
: [](OpPassManager &) {};
158+
} else {
159+
builderOpts.pipeline = opts.printIr ? [](OpPassManager &pm) {
160+
pipeline(pm);
161+
pm.addPass(createPrintIRPass());
162+
} : pipeline;
163+
}
164+
165+
gc::gpu::OclModuleBuilder builder{mlirMod, builderOpts};
166+
auto runtime = gcGetOrReport(gc::gpu::OclRuntime::get());
167+
auto oclMod = gcGetOrReport(builder.build(runtime));
168+
assert(oclMod->isStatic);
169+
170+
if (!opts.objDumpFile.getValue().empty()) {
171+
gcLogD("Dumping the compiled object to ", opts.objDumpFile.getValue());
172+
oclMod->dumpToObjectFile(opts.objDumpFile.getValue());
173+
}
174+
175+
auto queue = gcGetOrReport(runtime.createQueue());
176+
gc::gpu::OclContext ctx{runtime, queue};
177+
gc::gpu::StaticExecutor<0> exec{oclMod};
178+
gcLogD("Executing function ", opts.mainFuncName.c_str(), "()");
179+
exec(ctx);
180+
gcGetOrReport(ctx.finish());
181+
gcGetOrReport(runtime.releaseQueue(queue));
182+
return 0;
183+
}

test/mlir/test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ set(GC_OPT_TEST_DEPENDS
3232

3333
if(GC_ENABLE_IMEX)
3434
include(imex)
35-
list(APPEND GC_OPT_TEST_DEPENDS GcOpenclRuntime)
35+
list(APPEND GC_OPT_TEST_DEPENDS gc-gpu-runner)
3636
endif()
3737

3838
if(GC_ENABLE_BINDINGS_PYTHON)

test/mlir/test/gc/gpu-runner/XeGPU/f16_matmul_64x64.mlir

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// RUN: gc-opt %s --gc-gpu-pipeline="is-usm-args=false" \
2-
// RUN: | gc-cpu-runner -e main --entry-point-result=void \
3-
// RUN: --shared-libs=%mlir_runner_utils,%mlir_c_runner_utils,%opencl_runtime | FileCheck %s
1+
// RUN: gc-gpu-runner --shared-libs=%mlir_runner_utils %s | FileCheck %s
42
module{
53

64
func.func @linalg_matmul(%arg0: tensor<64x64xf16>,

test/mlir/test/gc/gpu-runner/XeGPU/f16_mlp_32x4096x4096x4096.mlir

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// RUN: gc-opt %s --gc-gpu-pipeline="is-usm-args=false" \
2-
// RUN: | gc-cpu-runner -e main --entry-point-result=void \
3-
// RUN: --shared-libs=%mlir_runner_utils,%mlir_c_runner_utils,%opencl_runtime | FileCheck %s
1+
// RUN: gc-gpu-runner --shared-libs=%mlir_runner_utils %s | FileCheck %s
42

53
module {
64
func.func @linalg_mlp(%arg0: tensor<32x4096xf16>, %arg1: tensor<4096x4096xf16>, %arg2 : tensor<32x4096xf16>,
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
11
if not config.gc_use_imex:
22
config.unsupported = True
3-
else: # FIXME: Remove this when the GPU runner is implemented.
4-
config.unsupported = True

test/mlir/test/gc/gpu-runner/mlp.mlir

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: gc-opt %s --gc-gpu-pipeline="is-usm-args=false" | gc-cpu-runner -e main -entry-point-result=void --shared-libs=%mlir_runner_utils,%mlir_c_runner_utils,%opencl_runtime | FileCheck %s
1+
// RUN: gc-gpu-runner --shared-libs=%mlir_runner_utils %s | FileCheck %s
2+
23
#map0 = affine_map<(d0, d1) -> (d1)>
34
#map1 = affine_map<(d0, d1) -> (d0, d1)>
45
#map2 = affine_map<(d0, d1, d2) -> (d0, d2)>

test/mlir/test/lit.cfg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True)
5050

5151
tool_dirs = [config.gc_tools_dir, config.llvm_tools_dir]
52-
tools = ["gc-opt", "gc-cpu-runner"]
52+
tools = ["gc-opt", "gc-cpu-runner", "gc-gpu-runner"]
5353

5454
llvm_config.add_tool_substitutions(tools, tool_dirs)
5555

0 commit comments

Comments
 (0)