Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/minimal-onnx-dialect.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Minimal ONNX dialect build

on:
pull_request:
push:

jobs:
build-minimal:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install prerequisites
run: |
sudo apt-get update
sudo apt-get install -y ninja-build cmake gcc g++ python3-pip
- name: Cache MLIR build
id: cache-mlir
uses: actions/cache@v3
with:
path: llvm-project
key: ${{ runner.os }}-mlir-${{ hashFiles('utils/clone-mlir.sh', 'utils/build-mlir.sh') }}
- name: Clone + build MLIR
if: steps.cache-mlir.outputs.cache-hit != 'true'
run: |
bash utils/clone-mlir.sh
bash utils/build-mlir.sh
- name: Configure minimal build
run: |
cmake -S . -B build -G Ninja \
-DMLIR_DIR=$GITHUB_WORKSPACE/llvm-project/build/lib/cmake/mlir \
-DONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT=ON \
-DCMAKE_BUILD_TYPE=Release
- name: Build test-onnx-to-mlir
run: |
cmake --build build --target test-onnx-to-mlir -j2
- name: Smoke test
run: |
echo 'digraph G { }' > /tmp/empty.onnx || true
# Use a known small ONNX from torch-mlir tests if present in tree; otherwise skip.
if [ -f third_party/onnx/onnx/backend/test/data/node/test_relu/model.onnx ]; then
build/Release/bin/test-onnx-to-mlir third_party/onnx/onnx/backend/test/data/node/test_relu/model.onnx | head -n 20
else
echo 'Minimal build completed.'
fi

34 changes: 24 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ option(ONNX_MLIR_ENABLE_WERROR "Enable warnings as errors." OFF)
option(ONNX_MLIR_SUPPRESS_THIRD_PARTY_WARNINGS "Suppress warning in third_party code." ON)
option(ONNX_MLIR_ENABLE_JAVA "Set to ON for building the Java runtime, tools, and tests" ON)
option(ONNX_MLIR_ENABLE_PYRUNTIME_LIGHT "Set to ON for building Python driver of running the compiled model without llvm-project." OFF)
option(ONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT "Build only ONNX dialect without lowering passes and runtime" OFF)

set(CMAKE_CXX_STANDARD 17)

Expand Down Expand Up @@ -162,7 +163,10 @@ endif()
set(CMAKE_MESSAGE_LOG_LEVEL NOTICE)

# Add third party subdirectories and define options appropriate to run their cmakes.
if (ONNX_MLIR_ENABLE_PYRUNTIME_LIGHT)
if (ONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT)
# Minimal build: only include ONNX protobuf library.
add_subdirectory(third_party/onnx)
elseif (ONNX_MLIR_ENABLE_PYRUNTIME_LIGHT)
add_subdirectory(third_party/onnx)
add_subdirectory(third_party/pybind11)
else()
Expand Down Expand Up @@ -195,13 +199,15 @@ endif()
# compile flags updated via llvm_update_compile_flags, so we need to do that to
# benchmark and rapidcheck as well, so that we can successfully link against them.
# Otherwise, some of the flags for exceptions (among others) are not set correctly.
llvm_update_compile_flags(benchmark)
llvm_update_compile_flags(benchmark_main)
llvm_update_compile_flags(rapidcheck)
if (NOT ONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT)
llvm_update_compile_flags(benchmark)
llvm_update_compile_flags(benchmark_main)
llvm_update_compile_flags(rapidcheck)

if (ONNX_MLIR_ENABLE_STABLEHLO)
llvm_update_compile_flags(stablehlo-opt)
llvm_update_compile_flags(stablehlo-translate)
if (ONNX_MLIR_ENABLE_STABLEHLO)
llvm_update_compile_flags(stablehlo-opt)
llvm_update_compile_flags(stablehlo-translate)
endif()
endif()

# Increase the log level for onnx-mlir
Expand All @@ -216,16 +222,24 @@ if (ONNX_MLIR_SUPPRESS_THIRD_PARTY_WARNINGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSUPPRESS_THIRD_PARTY_WARNINGS")
endif()

if (ONNX_MLIR_ENABLE_STABLEHLO)
if (ONNX_MLIR_ENABLE_STABLEHLO AND NOT ONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT)
add_compile_definitions(ONNX_MLIR_ENABLE_STABLEHLO)
endif()

if (ONNX_MLIR_ENABLE_PYRUNTIME_LIGHT)
if (ONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT)
# Minimal build: only include headers and ONNX dialect source.
add_subdirectory(include)
add_subdirectory(src/Interface)
add_subdirectory(src/Support)
add_subdirectory(src/Builder)
add_subdirectory(src/Dialect/Mlir)
add_subdirectory(src/Dialect/ONNX)
elseif (ONNX_MLIR_ENABLE_PYRUNTIME_LIGHT)
add_subdirectory(src)
else()
add_subdirectory(utils)
add_subdirectory(include)
add_subdirectory(src)
add_subdirectory(docs)
add_subdirectory(test)
endif()
endif()
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,38 @@ After installation, an `onnx-mlir` executable should appear in the `build/Debug/
If you have difficulties building, rebuilding, or testing `onnx-mlir`, check this [page](docs/TestingHighLevel.md) for helpful hints.


### Minimal build for ONNX dialect only

For consumers that only need the ONNX dialect (without lowering passes, runtime, or non-essential dialects), configure with:

```
cmake -S . -B build -G Ninja \
-DMLIR_DIR=/path/to/llvm-project/build/lib/cmake/mlir \
-DONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT=ON \
-DCMAKE_BUILD_TYPE=Release

cmake --build build --target test-onnx-to-mlir -j$(nproc)
```

This builds only the following components:
- `include/`
- `src/Interface/` (only interfaces required by ONNX)
- `src/Support/`
- `src/Builder/`
- `src/Dialect/Mlir/`
- `src/Dialect/ONNX/`

And provides a small test executable `test-onnx-to-mlir` that loads an ONNX model and prints ONNX dialect IR:

```
build/Release/bin/test-onnx-to-mlir model.onnx > model.mlir
```

Notes:
- Release builds are recommended to reduce memory usage during compilation.
- SpecializedKernel and Krnl dependencies are excluded in this mode.


## Using ONNX-MLIR

The usage of `onnx-mlir` is as such:
Expand Down
48 changes: 48 additions & 0 deletions docs/MinimalONNXDialectBuild.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--- SPDX-License-Identifier: Apache-2.0 -->

## Minimal ONNX dialect build

This document describes how to build a minimal subset of ONNX-MLIR that exposes only the ONNX dialect and the minimal helpers required to parse ONNX models and produce ONNX dialect MLIR.

### Rationale

Some projects want to import the ONNX dialect IR without bringing the full onnx-mlir stack (lowering passes, Krnl dialect, runtime). The CMake option `ONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT` enables such a build.

### What gets built

When `-DONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT=ON` is set, the following subdirectories are included:

- `include/`
- `src/Interface/` (ShapeInference, ResultTypeInference, HasOnnxSubgraph, ShapeHelper)
- `src/Support/`
- `src/Builder/` (for `ImportFrontendModelFile` and builders)
- `src/Dialect/Mlir/` (utility builders only; no Krnl or Compiler dependencies)
- `src/Dialect/ONNX/`

In addition, a small utility `test-onnx-to-mlir` is built to load an ONNX model and print the ONNX dialect IR.

### Configure and build

```
cmake -S . -B build -G Ninja \
-DMLIR_DIR=/path/to/llvm-project/build/lib/cmake/mlir \
-DONNX_MLIR_ENABLE_ONLY_ONNX_DIALECT=ON \
-DCMAKE_BUILD_TYPE=Release

cmake --build build --target test-onnx-to-mlir -j$(nproc)
```

Release builds are recommended to lower memory usage during compilation.

### Using the test helper

```
build/Release/bin/test-onnx-to-mlir /path/to/model.onnx > model.mlir
```

### Notes

- Krnl and Compiler modules are excluded.
- SpecializedKernel interface is excluded.
- The minimal build still requires the upstream LLVM/MLIR toolchain and ONNX protobuf.

2 changes: 1 addition & 1 deletion src/Builder/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ add_onnx_mlir_library(OMBuilder
configure_file(OpBuildTable.inc.dc.in
${CMAKE_CURRENT_BINARY_DIR}/OpBuildTable.inc.dc
@ONLY
)
)
5 changes: 0 additions & 5 deletions src/Dialect/Mlir/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@ add_onnx_mlir_library(OMMlirDialects
DialectBuilder.cpp
VectorMachineSupport.cpp

DEPENDS
OMKrnlIncGen
OMSpecializedKernelOpInterface

LINK_LIBS PUBLIC
OMCompilerOptions
MLIRMathDialect
MLIRAffineDialect
MLIRSCFDialect
Expand Down
5 changes: 0 additions & 5 deletions src/Dialect/Mlir/DialectBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include "llvm/Support/Debug.h"

// Please do not add dependences on ONNX or KRNL dialects.
#include "src/Compiler/CompilerOptions.hpp"
#include "src/Dialect/Mlir/DialectBuilder.hpp"
#include "src/Dialect/Mlir/VectorMachineSupport.hpp"

Expand Down Expand Up @@ -1757,16 +1756,12 @@ Value MemRefBuilder::dim(Value val, Value index) const {

void MemRefBuilder::prefetch(Value memref, ValueRange indices, bool isWrite,
unsigned locality, bool isData) {
if (disableMemRefPrefetch)
return;
b().create<memref::PrefetchOp>(
loc(), memref, indices, isWrite, locality, isData);
}

void MemRefBuilder::prefetchIE(Value memref, ArrayRef<IndexExpr> indices,
bool isWrite, unsigned locality, bool isData) {
if (disableMemRefPrefetch)
return;
SmallVector<Value, 4> indexVals;
IndexExpr::getValues(indices, indexVals);
prefetch(memref, indexVals, isWrite, locality, isData);
Expand Down
26 changes: 24 additions & 2 deletions src/Dialect/Mlir/VectorMachineSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// =============================================================================

#include "src/Dialect/Mlir/VectorMachineSupport.hpp"
#include "src/Compiler/CompilerOptions.hpp"

#include "mlir/IR/BuiltinTypes.h"
#include "llvm/Support/Debug.h"
Expand All @@ -22,6 +21,29 @@ using namespace mlir;

namespace onnx_mlir {

// Minimal version of getZArchNum to avoid dependency on Compiler module
namespace {
int64_t decodeZArchNum(std::string str) {
if (str == "arch12" || str == "z14") // Z14 and equivalents.
return 12;
if (str == "arch13" || str == "z15") // Z15 and equivalents.
return 13;
if (str == "arch14" || str == "z16") // Z16 and equivalents.
return 14;
if (str == "arch15" || str == "z17") // Z17 and equivalents.
return 15;
return -1;
}

int64_t getZArchNumLocal(const std::string &arch, const std::string cpu) {
// Give priority to march, use (deprecated) mcpu if march is not defined.
int64_t num = decodeZArchNum(arch);
if (num == -1)
num = decodeZArchNum(cpu);
return num;
}
} // anonymous namespace

// =============================================================================
// Handling of global vector machine support pointer

Expand All @@ -31,7 +53,7 @@ namespace onnx_mlir {
/*static*/ void VectorMachineSupport::setGlobalVectorMachineSupport(
const std::string &arch, const std::string &cpu, const std::string &attr) {
// IBM Z servers use march (deprecated mcpu), process here.
int64_t zArchNum = getZArchNum(arch, cpu);
int64_t zArchNum = getZArchNumLocal(arch, cpu);
if (zArchNum == 12) {
globalVectorMachineSupport = new ZArch12VectorMachineSupport();
} else if (zArchNum == 13) {
Expand Down
15 changes: 15 additions & 0 deletions src/Dialect/ONNX/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,22 @@ add_onnx_mlir_library(OMONNXOps
MLIRMemRefTransforms
)

# Add the generated directory to the include path so interface headers can find the generated files
target_include_directories(OMONNXOps PRIVATE ${GEN_DIR})

configure_file(ONNXOps.td.inc.dc.in
${CMAKE_CURRENT_BINARY_DIR}/ONNXOps.td.inc.dc
@ONLY
)

# Add test executable
add_onnx_mlir_executable(test-onnx-to-mlir
test-onnx-to-mlir.cpp

LINK_LIBS PRIVATE
OMONNXOps
OMBuilder
MLIRFuncDialect
MLIRSupport
LLVMSupport
)
47 changes: 47 additions & 0 deletions src/Dialect/ONNX/test-onnx-to-mlir.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// test-onnx-to-mlir.cpp

#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/DialectRegistry.h"
#include "mlir/IR/MLIRContext.h"

#include "src/Builder/FrontendDialectTransformer.hpp"
#include "src/Dialect/ONNX/ONNXDialect.hpp"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/raw_ostream.h"

int main(int argc, char **argv) {
llvm::InitLLVM y(argc, argv);

if (argc != 2) {
llvm::errs() << "Usage: test-onnx-to-mlir <input.onnx>\n";
return 1;
}

mlir::MLIRContext context;

// Register the ONNX dialect.
mlir::DialectRegistry registry;
registry.insert<mlir::func::FuncDialect>();
registry.insert<mlir::ONNXDialect>();
context.appendDialectRegistry(registry);
context.loadAllAvailableDialects();

// Import the ONNX model.
mlir::OwningOpRef<mlir::ModuleOp> module;
std::string errorMessage;
onnx_mlir::ImportOptions options;

int result = onnx_mlir::ImportFrontendModelFile(
argv[1], context, module, &errorMessage, options);

if (result != 0) {
llvm::errs() << "Failed to import model: " << errorMessage << "\n";
return 1;
}

llvm::outs() << "Successfully imported ONNX model!\n";
module->print(llvm::outs());

return 0;
}
Loading
Loading