From f4145aeab51693d6a3a62a988ea1aba8ce172fd1 Mon Sep 17 00:00:00 2001 From: maxwellflitton Date: Tue, 14 Jan 2025 00:34:43 +0000 Subject: [PATCH] mapping build steps --- modules/c-wrapper/Cargo.toml | 10 ++++-- modules/c-wrapper/Dockerfile | 17 +++++++--- modules/c-wrapper/README.md | 20 ------------ modules/c-wrapper/build-context/Dockerfile | 21 ++++++++++--- .../c-wrapper/scripts/build-docker.sh | 3 +- .../c-wrapper/scripts/prep_tests.sh | 22 ++++++++++++- .../tests/test_utils/c_lib_loader.py | 15 +++++++++ modules/c-wrapper/scripts/build-docker.sh | 1 + modules/c-wrapper/scripts/prep_tests.sh | 22 ++++++++++++- .../tests/test_utils/c_lib_loader.py | 15 +++++++++ modules/core/Cargo.toml | 2 +- modules/core/src/execution/session.rs | 31 ++++++++++++++++++- 12 files changed, 141 insertions(+), 38 deletions(-) delete mode 100644 modules/c-wrapper/README.md diff --git a/modules/c-wrapper/Cargo.toml b/modules/c-wrapper/Cargo.toml index 1274cac..46ee50a 100644 --- a/modules/c-wrapper/Cargo.toml +++ b/modules/c-wrapper/Cargo.toml @@ -4,8 +4,8 @@ version = "0.1.0" edition = "2021" [dependencies] -surrealml-core = { path = "../core" } -uuid = { version = "1.4.1", features = ["v4"] } +surrealml-core = { path = "../core", features = ["dynamic"] } +uuid = { version = "1.11.1", features = ["v4"] } ndarray = "0.16.1" # for the uploading the model to the server @@ -15,3 +15,9 @@ base64 = "0.13" [lib] crate-type = ["cdylib"] + +[build-dependencies] +reqwest = { version = "0.12.12", features = ["blocking", "json"] } +# tokio = { version = "1", features = ["full"] } # Required for reqwest +tar = "0.4" # For extracting tar files +flate2 = "1.0" # For handling gzip diff --git a/modules/c-wrapper/Dockerfile b/modules/c-wrapper/Dockerfile index 4cbed37..584f533 100644 --- a/modules/c-wrapper/Dockerfile +++ b/modules/c-wrapper/Dockerfile @@ -11,6 +11,7 @@ RUN apt-get update && apt-get install -y \ curl \ gnupg \ lsb-release \ + vim \ && rm -rf /var/lib/apt/lists/* # Set the working directory @@ -20,13 +21,17 @@ WORKDIR /app COPY . . # Download ONNX Runtime 1.20.0 -RUN wget https://github.com/microsoft/onnxruntime/releases/download/v1.20.0/onnxruntime-linux-x64-1.20.0.tgz \ - && tar -xvf onnxruntime-linux-x64-1.20.0.tgz \ - && mv onnxruntime-linux-x64-1.20.0 /onnxruntime +# RUN wget https://github.com/microsoft/onnxruntime/releases/download/v1.20.0/onnxruntime-linux-x64-1.20.0.tgz \ +# && tar -xvf onnxruntime-linux-x64-1.20.0.tgz \ +# && mv onnxruntime-linux-x64-1.20.0 /onnxruntime # Set the ONNX Runtime library path -ENV ORT_LIB_LOCATION=/onnxruntime/lib -ENV LD_LIBRARY_PATH=$ORT_LIB_LOCATION:$LD_LIBRARY_PATH +# ENV ORT_LIB_LOCATION=/onnxruntime/lib +# ENV LD_LIBRARY_PATH=$ORT_LIB_LOCATION:$LD_LIBRARY_PATH + +# Set the ONNX Runtime library path +# ENV ORT_LIB_LOCATION=$(pwd)/c-wrapper/tests/test_utils/onnxruntime/lib +# ENV LD_LIBRARY_PATH=$ORT_LIB_LOCATION:$LD_LIBRARY_PATH # install python for the tests RUN apt-get update && apt-get install -y python3 python3-pip @@ -34,5 +39,7 @@ RUN apt-get update && apt-get install -y python3 python3-pip # Clean and build the Rust project RUN cd c-wrapper/scripts && bash prep_tests.sh +# RUN rm /onnxruntime + # Run the tests CMD ["bash", "c-wrapper/scripts/run_tests.sh"] diff --git a/modules/c-wrapper/README.md b/modules/c-wrapper/README.md deleted file mode 100644 index dc69ec2..0000000 --- a/modules/c-wrapper/README.md +++ /dev/null @@ -1,20 +0,0 @@ - -# C Wrapper - -This workspace is a C wrapper for the `surrealml-core` library. This enables us to no longer need `PyO3` and we can also use this library in other languages. - -## Testing - -To test this C wrapper we first need to build the C lib and position it in the correct location for the Python tests to load the library. We can perform this setup with the following command: - -```bash -sh ./scripts/prep_tests.sh -``` - -This will build the C lib in debug mode and place it in the correct location for the Python tests to load the library. We can then run the tests with the following command: - -```bash -sh ./scripts/run_tests.sh -``` - -If you setup pycharm to put your Python tests through a debugger, you need to open pycharm in the root of this workspace and set the `tests` directory as the sources root. This will allow you to point and click on specific tests and run them through a debugger. diff --git a/modules/c-wrapper/build-context/Dockerfile b/modules/c-wrapper/build-context/Dockerfile index dfa8da9..584f533 100644 --- a/modules/c-wrapper/build-context/Dockerfile +++ b/modules/c-wrapper/build-context/Dockerfile @@ -7,6 +7,11 @@ RUN apt-get update && apt-get install -y \ build-essential \ libssl-dev \ pkg-config \ + ca-certificates \ + curl \ + gnupg \ + lsb-release \ + vim \ && rm -rf /var/lib/apt/lists/* # Set the working directory @@ -16,13 +21,17 @@ WORKDIR /app COPY . . # Download ONNX Runtime 1.20.0 -RUN wget https://github.com/microsoft/onnxruntime/releases/download/v1.20.0/onnxruntime-linux-x64-1.20.0.tgz \ - && tar -xvf onnxruntime-linux-x64-1.20.0.tgz \ - && mv onnxruntime-linux-x64-1.20.0 /onnxruntime +# RUN wget https://github.com/microsoft/onnxruntime/releases/download/v1.20.0/onnxruntime-linux-x64-1.20.0.tgz \ +# && tar -xvf onnxruntime-linux-x64-1.20.0.tgz \ +# && mv onnxruntime-linux-x64-1.20.0 /onnxruntime # Set the ONNX Runtime library path -ENV ORT_LIB_LOCATION=/onnxruntime/lib -ENV LD_LIBRARY_PATH=$ORT_LIB_LOCATION:$LD_LIBRARY_PATH +# ENV ORT_LIB_LOCATION=/onnxruntime/lib +# ENV LD_LIBRARY_PATH=$ORT_LIB_LOCATION:$LD_LIBRARY_PATH + +# Set the ONNX Runtime library path +# ENV ORT_LIB_LOCATION=$(pwd)/c-wrapper/tests/test_utils/onnxruntime/lib +# ENV LD_LIBRARY_PATH=$ORT_LIB_LOCATION:$LD_LIBRARY_PATH # install python for the tests RUN apt-get update && apt-get install -y python3 python3-pip @@ -30,5 +39,7 @@ RUN apt-get update && apt-get install -y python3 python3-pip # Clean and build the Rust project RUN cd c-wrapper/scripts && bash prep_tests.sh +# RUN rm /onnxruntime + # Run the tests CMD ["bash", "c-wrapper/scripts/run_tests.sh"] diff --git a/modules/c-wrapper/build-context/c-wrapper/scripts/build-docker.sh b/modules/c-wrapper/build-context/c-wrapper/scripts/build-docker.sh index 63f665e..3ac8066 100644 --- a/modules/c-wrapper/build-context/c-wrapper/scripts/build-docker.sh +++ b/modules/c-wrapper/build-context/c-wrapper/scripts/build-docker.sh @@ -30,5 +30,4 @@ cd "$BUILD_DIR" docker build --no-cache -t c-wrapper-tests . docker run c-wrapper-tests - -# docker run -it c-wrapper-tests /bin/bash \ No newline at end of file +# docker run -it c-wrapper-tests /bin/bash diff --git a/modules/c-wrapper/build-context/c-wrapper/scripts/prep_tests.sh b/modules/c-wrapper/build-context/c-wrapper/scripts/prep_tests.sh index bf857e1..9bcd32a 100644 --- a/modules/c-wrapper/build-context/c-wrapper/scripts/prep_tests.sh +++ b/modules/c-wrapper/build-context/c-wrapper/scripts/prep_tests.sh @@ -6,6 +6,26 @@ cd $SCRIPTPATH cd .. +# download onnxruntime +# Detect operating system +OS=$(uname -s | tr '[:upper:]' '[:lower:]') + +# Detect architecture +ARCH=$(uname -m) + +# Download the correct onnxruntime +if [ "$ARCH" == "x86_64" ] && [ "$OS" == "linux" ]; then + wget https://github.com/microsoft/onnxruntime/releases/download/v1.20.0/onnxruntime-linux-x64-1.20.0.tgz + tar -xvf onnxruntime-linux-x64-1.20.0.tgz + mv onnxruntime-linux-x64-1.20.0 tests/test_utils/onnxruntime +else + echo "Unsupported operating system and arch: $OS $ARCH" + exit 1 +fi + +export ORT_LIB_LOCATION=$(pwd)/tests/test_utils/onnxruntime/lib +export LD_LIBRARY_PATH=$ORT_LIB_LOCATION:$LD_LIBRARY_PATH + cargo build # Get the operating system @@ -42,4 +62,4 @@ if [ -f "$SOURCE_DIR/$LIB_NAME" ]; then else echo "Library not found: $SOURCE_DIR/$LIB_NAME" exit 1 -fi \ No newline at end of file +fi diff --git a/modules/c-wrapper/build-context/c-wrapper/tests/test_utils/c_lib_loader.py b/modules/c-wrapper/build-context/c-wrapper/tests/test_utils/c_lib_loader.py index e1d281f..64908b2 100644 --- a/modules/c-wrapper/build-context/c-wrapper/tests/test_utils/c_lib_loader.py +++ b/modules/c-wrapper/build-context/c-wrapper/tests/test_utils/c_lib_loader.py @@ -1,6 +1,7 @@ import ctypes import platform from pathlib import Path +import os def load_library(lib_name: str = "libc_wrapper") -> ctypes.CDLL: @@ -16,14 +17,28 @@ def load_library(lib_name: str = "libc_wrapper") -> ctypes.CDLL: current_dir = Path(__file__).parent system_name = platform.system() + # os.environ["ORT_LIB_LOCATION"] = str(current_dir.joinpath("onnxruntime.dll")) + if system_name == "Windows": lib_path = current_dir.joinpath(f"{lib_name}.dll") + onnx_path = current_dir.joinpath("onnxruntime").joinpath("lib").joinpath("onnxruntime.dll") elif system_name == "Darwin": # macOS lib_path = current_dir.joinpath(f"{lib_name}.dylib") + onnx_path = current_dir.joinpath("onnxruntime").joinpath("lib").joinpath("onnxruntime.dylib") elif system_name == "Linux": lib_path = current_dir.joinpath(f"{lib_name}.so") + onnx_path = current_dir.joinpath("onnxruntime").joinpath("lib").joinpath("onnxruntime.so.1") else: raise OSError(f"Unsupported operating system: {system_name}") + + + # onnx_lib_path = current_dir.joinpath("onnxruntime").joinpath("lib") + # current_ld_library_path = os.environ.get("LD_LIBRARY_PATH", "") + # # Update LD_LIBRARY_PATH + # os.environ["LD_LIBRARY_PATH"] = f"{onnx_lib_path}:{current_ld_library_path}" + # os.environ["ORT_LIB_LOCATION"] = str(onnx_lib_path) + + ctypes.CDLL(str(onnx_path), mode=ctypes.RTLD_GLOBAL) if not lib_path.exists(): raise FileNotFoundError(f"Shared library not found at: {lib_path}") diff --git a/modules/c-wrapper/scripts/build-docker.sh b/modules/c-wrapper/scripts/build-docker.sh index a2555f0..3ac8066 100644 --- a/modules/c-wrapper/scripts/build-docker.sh +++ b/modules/c-wrapper/scripts/build-docker.sh @@ -30,3 +30,4 @@ cd "$BUILD_DIR" docker build --no-cache -t c-wrapper-tests . docker run c-wrapper-tests +# docker run -it c-wrapper-tests /bin/bash diff --git a/modules/c-wrapper/scripts/prep_tests.sh b/modules/c-wrapper/scripts/prep_tests.sh index bf857e1..9bcd32a 100644 --- a/modules/c-wrapper/scripts/prep_tests.sh +++ b/modules/c-wrapper/scripts/prep_tests.sh @@ -6,6 +6,26 @@ cd $SCRIPTPATH cd .. +# download onnxruntime +# Detect operating system +OS=$(uname -s | tr '[:upper:]' '[:lower:]') + +# Detect architecture +ARCH=$(uname -m) + +# Download the correct onnxruntime +if [ "$ARCH" == "x86_64" ] && [ "$OS" == "linux" ]; then + wget https://github.com/microsoft/onnxruntime/releases/download/v1.20.0/onnxruntime-linux-x64-1.20.0.tgz + tar -xvf onnxruntime-linux-x64-1.20.0.tgz + mv onnxruntime-linux-x64-1.20.0 tests/test_utils/onnxruntime +else + echo "Unsupported operating system and arch: $OS $ARCH" + exit 1 +fi + +export ORT_LIB_LOCATION=$(pwd)/tests/test_utils/onnxruntime/lib +export LD_LIBRARY_PATH=$ORT_LIB_LOCATION:$LD_LIBRARY_PATH + cargo build # Get the operating system @@ -42,4 +62,4 @@ if [ -f "$SOURCE_DIR/$LIB_NAME" ]; then else echo "Library not found: $SOURCE_DIR/$LIB_NAME" exit 1 -fi \ No newline at end of file +fi diff --git a/modules/c-wrapper/tests/test_utils/c_lib_loader.py b/modules/c-wrapper/tests/test_utils/c_lib_loader.py index e1d281f..64908b2 100644 --- a/modules/c-wrapper/tests/test_utils/c_lib_loader.py +++ b/modules/c-wrapper/tests/test_utils/c_lib_loader.py @@ -1,6 +1,7 @@ import ctypes import platform from pathlib import Path +import os def load_library(lib_name: str = "libc_wrapper") -> ctypes.CDLL: @@ -16,14 +17,28 @@ def load_library(lib_name: str = "libc_wrapper") -> ctypes.CDLL: current_dir = Path(__file__).parent system_name = platform.system() + # os.environ["ORT_LIB_LOCATION"] = str(current_dir.joinpath("onnxruntime.dll")) + if system_name == "Windows": lib_path = current_dir.joinpath(f"{lib_name}.dll") + onnx_path = current_dir.joinpath("onnxruntime").joinpath("lib").joinpath("onnxruntime.dll") elif system_name == "Darwin": # macOS lib_path = current_dir.joinpath(f"{lib_name}.dylib") + onnx_path = current_dir.joinpath("onnxruntime").joinpath("lib").joinpath("onnxruntime.dylib") elif system_name == "Linux": lib_path = current_dir.joinpath(f"{lib_name}.so") + onnx_path = current_dir.joinpath("onnxruntime").joinpath("lib").joinpath("onnxruntime.so.1") else: raise OSError(f"Unsupported operating system: {system_name}") + + + # onnx_lib_path = current_dir.joinpath("onnxruntime").joinpath("lib") + # current_ld_library_path = os.environ.get("LD_LIBRARY_PATH", "") + # # Update LD_LIBRARY_PATH + # os.environ["LD_LIBRARY_PATH"] = f"{onnx_lib_path}:{current_ld_library_path}" + # os.environ["ORT_LIB_LOCATION"] = str(onnx_lib_path) + + ctypes.CDLL(str(onnx_path), mode=ctypes.RTLD_GLOBAL) if not lib_path.exists(): raise FileNotFoundError(f"Shared library not found at: {lib_path}") diff --git a/modules/core/Cargo.toml b/modules/core/Cargo.toml index 0a8d8b9..8d2dac1 100644 --- a/modules/core/Cargo.toml +++ b/modules/core/Cargo.toml @@ -18,10 +18,10 @@ onnx-tests = [] torch-tests = [] tensorflow-tests = [] gpu = [] +dynamic = ["ort/load-dynamic"] [dependencies] regex = "1.9.3" -# ort = { version = "1.16.2", features = ["load-dynamic"], default-features = false } ort = { version = "2.0.0-rc.9", features = [ "cuda", "ndarray" ]} ndarray = "0.16.1" once_cell = "1.18.0" diff --git a/modules/core/src/execution/session.rs b/modules/core/src/execution/session.rs index 1ebf097..ab78cfa 100644 --- a/modules/core/src/execution/session.rs +++ b/modules/core/src/execution/session.rs @@ -3,6 +3,15 @@ use ort::session::Session; use crate::errors::error::{SurrealError, SurrealErrorStatus}; use crate::safe_eject; +#[cfg(feature = "dynamic")] +use once_cell::sync::Lazy; +#[cfg(feature = "dynamic")] +use ort::environment::{EnvironmentBuilder, Environment}; +#[cfg(feature = "dynamic")] +use std::sync::{Arc, Mutex}; + +use std::sync::LazyLock; + /// Creates a session for a model. /// @@ -26,4 +35,24 @@ pub fn get_session(model_bytes: Vec) -> Result { let session: Session = safe_eject!(builder .commit_from_memory(&model_bytes), SurrealErrorStatus::Unknown); Ok(session) -} \ No newline at end of file +} + + +#[cfg(feature = "dynamic")] +pub static ORT_ENV: LazyLock>>>> = LazyLock::new(|| Arc::new(Mutex::new(None))); + + +#[cfg(feature = "dynamic")] +pub fn set_environment(dylib_path: String) -> Result<(), SurrealError> { + + let outcome: EnvironmentBuilder = ort::init_from(dylib_path); + match outcome.commit() { + Ok(env) => { + ORT_ENV.lock().unwrap().replace(env); + }, + Err(e) => { + return Err(SurrealError::new(e.to_string(), SurrealErrorStatus::Unknown)); + } + } + Ok(()) +}