Skip to content

Commit

Permalink
document
Browse files Browse the repository at this point in the history
Signed-off-by: Chen Tong <chentong@us.ibm.com>
  • Loading branch information
chentong319 committed Jan 15, 2025
1 parent 0ee214f commit beff2e3
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 40 deletions.
35 changes: 35 additions & 0 deletions docs/BuildPyRuntimeLit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# How to build and use PyRuntime lit

## Purpsoe

PyRuntime lit is a different way to build the original PyRuntime (src/Runtime/python).
All necessary dependence, such as llvm_project and onnx-mlir compiler is removed. The purpose is to easily build the python driver for the model execution on
different systems. Currently, only the OMTenserUtils (src/Runtime), Python driver (src/Runtime/python), third_party/onnx and third_party/pybind11 are built.

The build of PyRuntime lit is controlled by a CMake option: ONNX_MLIR_ENABLE_PYRUNTIME_LIT. Without this option to cmake, the whole system remains the same.

## Functionalities
1. Build the python driver without llvm_project and onnx-mlir compiler built.
2. The python driver can be used with utils/RunONNXModel.py, or onnxmlir python package.
3. With PyRuntime lit, the compiler has not been built locally and docker image of onnx-mlir has to be usd to compile the model. The onnxmlir package contains
the python code to use python docker package to perform the compilation. Alternatively, the old script, onnx-mlir/docker/onnx-mlir.py, can do the fulfill the same task with subprocess and docker CLI.

## How to use
You can find the script for build and run at "onnx-mlir/utils/build-pyruntime-lit.sh.
```
#!/bin/bash
# Assume you are in an empty directory for build in cloned onnx-mlir.
# Usually it is "your_path/onnx-mlir/build"
# then you can run this script as "../util/build-pyruntime-lit.sh"
cmake .. -DONNX_MLIR_ENABLE_PYRUNTIME_LIT=ON
make
make OMCreatePyRuntimePackage
# Install the package
pip3 install src/Runtime/python/onnxmlir
# Run test case
python3 src/Runtime/python/onnxmlir/test/test_1.py
```
9 changes: 4 additions & 5 deletions src/Runtime/ExecutionSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include <errno.h>
#include <string.h>


#include <iostream>
#include <memory>
#include <sstream>
Expand Down Expand Up @@ -83,7 +82,7 @@ void ExecutionSession::Init(
throw std::runtime_error(reportLibraryOpeningError(sharedLibPath));
#else
// Copy code from llvm/lib/Support/DynamicLibrary.cpp, especially the flags
// ToFix: copy the lock related code too.
// ToFix: copy the lock related code too.
_sharedLibraryHandle = dlopen(sharedLibPath.c_str(), RTLD_LAZY | RTLD_GLOBAL);
if (!_sharedLibraryHandle)
throw std::runtime_error(reportLibraryOpeningError(sharedLibPath));
Expand All @@ -96,7 +95,7 @@ void ExecutionSession::Init(
queryEntryPointsNameWithTag.c_str()));
#else
_queryEntryPointsFunc = reinterpret_cast<queryEntryPointsFuncType>(
dlsym(_sharedLibraryHandle, queryEntryPointsNameWithTag.c_str()));
dlsym(_sharedLibraryHandle, queryEntryPointsNameWithTag.c_str()));
#endif

if (!_queryEntryPointsFunc)
Expand Down Expand Up @@ -151,7 +150,7 @@ void ExecutionSession::Init(
}

ExecutionSession::~ExecutionSession() {
#ifndef ENABLE_PYRUNTIME_LIT
#ifndef ENABLE_PYRUNTIME_LIT
if (_sharedLibraryHandle.isValid())
llvm::sys::DynamicLibrary::closeLibrary(_sharedLibraryHandle);
#else
Expand All @@ -174,7 +173,7 @@ const std::string *ExecutionSession::queryEntryPoints(
void ExecutionSession::setEntryPoint(const std::string &entryPointName) {
if (!isInitialized)
throw std::runtime_error(reportInitError());
#ifndef ENABLE_PYRUNTIME_LIT
#ifndef ENABLE_PYRUNTIME_LIT
_entryPointFunc = reinterpret_cast<entryPointFuncType>(
_sharedLibraryHandle.getAddressOfSymbol(entryPointName.c_str()));
#else
Expand Down
2 changes: 1 addition & 1 deletion src/Runtime/ExecutionSession.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include "llvm/Support/DynamicLibrary.h"
typedef llvm::sys::DynamicLibrary DynamicLibraryHandleType;
#else
typedef void* DynamicLibraryHandleType;
typedef void *DynamicLibraryHandleType;
#endif

namespace onnx_mlir {
Expand Down
4 changes: 1 addition & 3 deletions src/Runtime/python/PyRuntime.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
try:
from .PyRuntimeC import OMExecutionSession as OMExecutionSession_
except ImportError:
raise ImportError(
"Failure to load the prebuild PyRuntimeC.*.so."
)
raise ImportError("Failure to load the prebuild PyRuntimeC.*.so.")
else:
try:
from PyRuntimeC import OMExecutionSession as OMExecutionSession_
Expand Down
6 changes: 3 additions & 3 deletions src/Runtime/python/onnxmlir/tests/test_standalone.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
import numpy as np
import onnxmlirdocker

#sess = onnxmlirdocker.InferenceSession("test_add.so")
# sess = onnxmlirdocker.InferenceSession("test_add.so")
sess = onnxmlirdocker.InferenceSession("test_add.onnx")

a = np.zeros((3, 4, 5), dtype=np.float32)
b = a + 4

# Run with list of array
#r = sess.run(None, [a, b])
# r = sess.run(None, [a, b])

# Run with dictionary
r = sess.run(None, {'x': a, 'y': b})
r = sess.run(None, {"x": a, "y": b})
print(r)
68 changes: 40 additions & 28 deletions src/Runtime/python/onnxmlirdocker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,42 @@
import tempfile
import json


def get_names_in_signature(signature):
names = []
names = []
# Load the input signature.
signature_dict = json.loads(signature)
for sig in signature_dict:
names.append(sig["name"])
return names


class InferenceSession:
def __init__(self, model_path, **kwargs):
if model_path.endswith(".mlir") :
if model_path.endswith(".mlir"):
model_suffix = ".mlir"
elif model_path.endswith(".onnx") :
elif model_path.endswith(".onnx"):
model_suffix = ".onnx"
elif model_path.endswith(".so") :
elif model_path.endswith(".so"):
self.compiled_lib = os.path.abspath(model_path)
self.session = self.getSession()
return;
else :
print(
"Invalid input model path. Must end with .onnx or .mlir or .onnxtext"
)
return
else:
print("Invalid input model path. Must end with .onnx or .mlir or .onnxtext")
exit(1)

if "compile-options" in kwargs.keys():
self.compile_options = kwargs["compile-options"]
else:
self.compile_options = ""


if "onnx-mlir-container" in kwargs.keys():
self.compiler_container = kwargs["onnx-mlir-container"]
else:
# Default image
# The compiler command may have different path in different image
#self.onnx_mlir_image = "ghcr.io/onnxmlir/onnx-mlir-dev"
# self.onnx_mlir_image = "ghcr.io/onnxmlir/onnx-mlir-dev"
self.onnx_mlir_image = "onnxmlir/onnx-mlir-dev"


# Path to mount the model to the image
self.container_model_dirname = "/myinput"
Expand All @@ -57,25 +55,41 @@ def __init__(self, model_path, **kwargs):
absolute_path = os.path.abspath(self.model_path)
self.model_basename = os.path.basename(absolute_path)
self.model_dirname = os.path.dirname(absolute_path)

# Compiled library
command_str += " " + self.compile_options
command_str += " " + os.path.join(self.container_model_dirname, self.model_basename)
command_str += " " + os.path.join(
self.container_model_dirname, self.model_basename
)

# ToFix: should use temporary directory for compilation, and
# use "-o" to put the compiled library in the temporary directory.
self.output_tempdir = tempfile.TemporaryDirectory()
self.output_dirname = self.output_tempdir.name
self.compiled_model = os.path.join(self.output_dirname, self.model_basename.removesuffix(model_suffix)+".so")
command_str += " -o " + os.path.join(self.container_output_dirname, self.model_basename.removesuffix(model_suffix))
self.compiled_model = os.path.join(
self.output_dirname, self.model_basename.removesuffix(model_suffix) + ".so"
)
command_str += " -o " + os.path.join(
self.container_output_dirname,
self.model_basename.removesuffix(model_suffix),
)

self.container_client = docker.from_env()
# Logically, the model directory could be mounted as read only.
# But wrong time error occurred with "r" mode
msg=self.container_client.containers.run(self.onnx_mlir_image,
msg = self.container_client.containers.run(
self.onnx_mlir_image,
command_str,
volumes={self.model_dirname: {'bind': self.container_model_dirname, 'mode': 'rw'}, self.output_dirname: {'bind': self.container_output_dirname, 'mode': 'rw'}
}
volumes={
self.model_dirname: {
"bind": self.container_model_dirname,
"mode": "rw",
},
self.output_dirname: {
"bind": self.container_output_dirname,
"mode": "rw",
},
},
)
print("afterwards tempdir: ", [f for f in os.listdir(self.output_dirname)])
self.session = self.getSession()
Expand All @@ -85,24 +99,22 @@ def getSession(self):
# are within the package. Path in the pakcage should be used.
# Otherwise, env variable ONNX_MLIR_HOME is used to for import path
if __package__ == "onnxmlir":
try:
try:
from .PyRuntime import OMExecutionSession
except ImportError:
raise ImportError(
" Error in importing PyRuntime for onnxmlir package"
)
raise ImportError(" Error in importing PyRuntime for onnxmlir package")

else:
if not os.environ.get("ONNX_MLIR_HOME", None):
raise RuntimeError(
"Environment variable ONNX_MLIR_HOME is not set, please set it to the path to "
"Environment variable ONNX_MLIR_HOME is not set, please set it to the path to "
"the HOME directory for onnx-mlir. The HOME directory for onnx-mlir refers to "
"the parent folder containing the bin, lib, etc sub-folders in which ONNX-MLIR "
"execu tables and libraries can be found, typically `onnx-mlir/build/Debug`"
)
"execu tables and libraries can be found, typically `onnx-mlir/build/Debug`"
)
RUNTIME_DIR = os.path.join(os.environ["ONNX_MLIR_HOME"], "lib")
sys.path.append(RUNTIME_DIR)
try:
try:
from PyRuntime import OMExecutionSession
except ImportError:
raise ImportError(
Expand Down Expand Up @@ -135,5 +147,5 @@ def run(self, outputname, input_feed, **kwargs):
# Provide random value inputs
print("error: input is not provided. ToFix: random input")
exit(1)

return self.session.run(inputs)
15 changes: 15 additions & 0 deletions utils/build-pyruntime-lit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

# Assume you are in an empty directory for build in cloned onnx-mlir.
# Usually it is "your_path/onnx-mlir/build"
# then you can run this script as "../util/build-pyruntime-lit.sh"

cmake .. -DONNX_MLIR_ENABLE_PYRUNTIME_LIT=ON
make
make OMCreatePyRuntimePackage

# Install the package
pip3 install src/Runtime/python/onnxmlir

# Run test case
python3 src/Runtime/python/onnxmlir/test/test_1.py

0 comments on commit beff2e3

Please sign in to comment.