diff --git a/.gitignore b/.gitignore index b74212a..2d38f88 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ npm-debug.log cargo.log cross.log lib/*.js -bin/**/* \ No newline at end of file +bin/**/* +.venv +/qairt \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a680507 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,110 @@ +cmake_minimum_required(VERSION 3.10) +project(executorch_all) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +include(executorch/build/Utils.cmake) + +# CONFIG + +option(EXECUTORCH_INSTALL_PATH "Path to install executorch" "" FORCE) + +set(link_libraries "executorch" "executorch_core") +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + list( + APPEND link_libraries + extension_data_loader + extension_module_static + portable_ops_lib + portable_kernels + ) +else() + list( + APPEND link_libraries + extension_data_loader + extension_module_static + optimized_native_cpu_ops_lib + optimized_kernels + portable_kernels + eigen_blas + quantized_ops_lib + quantized_kernels + custom_ops + extension_tensor + extension_runner_util + cpuinfo + pthreadpool + xnnpack_backend + XNNPACK + microkernels-prod + ) + if (CMAKE_SYSTEM_NAME STREQUAL "Windows" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") + list(APPEND link_libraries "qnn_executorch_backend") + endif() + if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(ET_CMAKE_ARGS "${ET_CMAKE_ARGS} -DEXECUTORCH_BUILD_COREML=ON") + endif() +endif() + +set(executorch_DIR ${EXECUTORCH_INSTALL_PATH}) +find_package(executorch REQUIRED CONFIG) + +# TOKENIZERS + +set(ABSL_ENABLE_INSTALL ON) +set(ABSL_PROPAGATE_CXX_STD ON) +add_subdirectory(executorch/extension/llm/third-party/abseil-cpp) +add_subdirectory(executorch/extension/llm/third-party/re2) +add_subdirectory(executorch/extension/llm/third-party/sentencepiece) + +file(GLOB_RECURSE TOKENIZER_SRCS + executorch/extension/llm/tokenizer/bpe_tokenizer.cpp + executorch/extension/llm/tokenizer/tiktoken.cpp +) +file(GLOB_RECURSE TOKENIZER_HDRS + executorch/extension/llm/tokenizer/*.h +) +add_library(tokenizer STATIC + ${TOKENIZER_SRCS} + ${TOKENIZER_HDRS} +) +target_include_directories(tokenizer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +# list( +# APPEND link_libraries +# tokenizer +# re2::re2 +# sentencepiece-static +# ) + + +# ALL + +add_library(executorch_all INTERFACE) + +target_link_options_shared_lib(executorch) +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_options_shared_lib(portable_ops_lib) +else() + target_link_options_shared_lib(optimized_native_cpu_ops_lib) + target_link_options_shared_lib(quantized_ops_lib) + target_link_options_shared_lib(custom_ops) + target_link_options_shared_lib(xnnpack_backend) + if (CMAKE_SYSTEM_NAME STREQUAL "Windows" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") + target_link_options_shared_lib(qnn_executorch_backend) + endif() + if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + target_link_options_shared_lib(coremldelegate) + endif() +endif() + +target_link_libraries(executorch_all INTERFACE ${link_libraries}) + +# INSTALL + +install(TARGETS executorch_all + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin +) diff --git a/Cargo.lock b/Cargo.lock index 78686ad..d45bed5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cmake" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a" +dependencies = [ + "cc", +] + [[package]] name = "cpp" version = "0.5.9" @@ -147,11 +156,13 @@ version = "0.0.0" dependencies = [ "build-target", "cc", + "cmake", "cpp", "cpp_build", "cpp_macros", "libc", "neon", + "project-root", ] [[package]] @@ -169,6 +180,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "project-root" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bccbff07d5ed689c4087d20d7307a52ab6141edeedf487c3876a55b86cf63df" + [[package]] name = "quote" version = "1.0.37" diff --git a/Cargo.toml b/Cargo.toml index 9a4afce..7db5b01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,5 @@ libc = "0.2" cc = "1.1.21" cpp_build = "0.5" build-target = "0.4" +cmake = "0.1" +project-root = "*" \ No newline at end of file diff --git a/build.rs b/build.rs index 00ffea3..3edda73 100644 --- a/build.rs +++ b/build.rs @@ -1,50 +1,13 @@ extern crate build_target; extern crate cpp_build; -use build_target::Os; -use std::path::Path; - -fn link_lib(lib_path: &Path, lib: &str, whole_link: bool) -> Result<(), ()> { - let so_ext = match build_target::target_os().unwrap() { - Os::Linux => "so", - Os::MacOs => "a", - Os::Windows => "dll", - _ => panic!("Unsupported OS"), - }; - let filename = match lib { - "extension_module" => format!("lib{}.{}", lib, so_ext), - "qnn_executorch_backend" => format!("lib{}.{}", lib, so_ext), - _ => format!("lib{}.a", lib), - }; - if lib_path.join(&filename).exists() { - if filename.ends_with(so_ext) && so_ext != "a" { - println!("cargo:rustc-link-lib=dylib={}", lib); - } else { - if whole_link { - println!("cargo:rustc-link-lib=static:+whole-archive={}", lib); - } else { - println!("cargo:rustc-link-lib=static={}", lib); - } - } - return Ok(()); - } - Err(()) -} +use std::path; +use build_target::{Arch, Os}; +use cmake::Config; fn main() { - println!("cargo:rerun-if-changed=src/sampler.rs"); - println!("cargo:rerun-if-changed=src/tensor.rs"); - println!("cargo:rerun-if-changed=src/tensor.hpp"); - println!("cargo:rerun-if-changed=src/module.rs"); - println!("cargo:rerun-if-changed=src/module.hpp"); - println!("cargo:rerun-if-changed=src/method_meta.rs"); - println!("cargo:rerun-if-changed=src/evalue.rs"); - println!("cargo:rerun-if-changed=src/evalue.hpp"); - println!("cargo:rerun-if-changed=src/eterror.rs"); - println!("cargo:rerun-if-changed=src/lib.rs"); - - let install_prefix = std::env::var("EXECUTORCH_INSTALL_PREFIX") - .unwrap_or_else(|_| "executorch/cmake-out".to_string()); - let lib_path = Path::new(&install_prefix).join("lib"); + println!("cargo:rerun-if-changed=executorch/version.txt"); + println!("cargo:rerun-if-changed=CMakeLists.txt"); + println!("cargo:rerun-if-changed=src/"); let node_platform = match std::env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() { "linux" => "linux", @@ -58,7 +21,70 @@ fn main() { _ => panic!("Unsupported arch"), }; - println!("cargo:rustc-link-search=native={}", lib_path.display()); + // // let executorch = cmake::build("."); + // let mut et = Config::new("executorch"); + // // debug flags + // if std::env::var("PROFILE").unwrap() == "debug" { + // et.define("EXECUTORCH_ENABLE_LOGGING", "ON"); + // et.define("EXECUTORCH_BUILD_XNNPACK", "ON"); + // et.define("EXECUTORCH_BUILD_EXTENSION_DATA_LOADER", "ON"); + // et.define("EXECUTORCH_BUILD_EXTENSION_MODULE", "ON"); + // } else { + // et.define("EXECUTORCH_BUILD_EXTENSION_DATA_LOADER", "ON"); + // et.define("EXECUTORCH_BUILD_EXTENSION_MODULE", "ON"); + // et.define("EXECUTORCH_BUILD_KERNELS_CUSTOM", "ON"); + // et.define("EXECUTORCH_BUILD_KERNELS_QUANTIZED", "ON"); + // et.define("EXECUTORCH_BUILD_KERNELS_OPTIMIZED", "ON"); + // et.define("EXECUTORCH_BUILD_EXTENSION_TENSOR", "ON"); + // et.define("EXECUTORCH_BUILD_CPUINFO", "ON"); + // et.define("EXECUTORCH_BUILD_XNNPACK", "ON"); + // et.define("EXECUTORCH_BUILD_PTHREADPOOL", "ON"); + // et.define("EXECUTORCH_BUILD_SDK", "ON"); + // et.define("EXECUTORCH_ENABLE_LOGGING", "ON"); + // if os == Os::Windows && arch == Arch::AARCH64 { + // if let Ok(qnn_sdk_root) = std::env::var("QNN_SDK_ROOT") { + // et.define("QNN_SDK_ROOT", qnn_sdk_root); + // et.define("EXECUTORCH_BUILD_QNN", "ON"); + // } + // } + // if os == Os::MacOs { + // et.define("EXECUTORCH_BUILD_COREML", "ON"); + // } + // } + // // resolve toolchain file absolute path + // // project_root::get_project_root().unwrap() + cmake/mingw-w64-aarch64.clang.toolchain.cmake + // let toolchain_file = Path::new(&project_root::get_project_root().unwrap()).join("cmake/mingw-w64-aarch64.clang.toolchain.cmake"); + // et.define("CMAKE_TOOLCHAIN_FILE", toolchain_file.display().to_string()); + // let et_path = et.build(); + // println!("cargo:rustc-link-search=native={}/lib", et_path.display()); + + let build_script = path::Path::new(&project_root::get_project_root().unwrap()).join("scripts/build.sh"); + assert!(build_script.exists(), "build.sh not found"); + let build_script_path = build_script.to_str().unwrap(); + let out_dir = path::absolute("build").unwrap().display().to_string(); + + // if env has no EXECUTORCH_INSTALL_PREFIX, run scripts/build.sh + if std::env::var("EXECUTORCH_INSTALL_PREFIX").is_err() { + let mut cmd = std::process::Command::new(build_script_path); + cmd.args(&[node_platform, node_arch, &out_dir]); + cmd.status().unwrap(); + } + + let et_path = std::env::var("EXECUTORCH_INSTALL_PREFIX").unwrap_or_else(|_| out_dir); + + println!("cargo:rustc-link-search=native={}/lib", et_path); + + let et_all = Config::new(".") + .define("EXECUTORCH_INSTALL_PATH", et_path) + .build(); + println!("cargo:rustc-link-search=native={}/lib", et_all.display()); + println!("cargo:rustc-link-lib=static=executorch_all"); + + // let install_prefix = std::env::var("EXECUTORCH_INSTALL_PREFIX") + // .unwrap_or_else(|_| "executorch/cmake-out".to_string()); + // let lib_path = Path::new(&install_prefix).join("lib"); + + // println!("cargo:rustc-link-search=native={}", lib_path.display()); // for nodejs/electron usage println!( @@ -74,56 +100,6 @@ fn main() { node_platform, node_arch ); - assert!(link_lib(&lib_path, "executorch", true).is_ok()); - if !link_lib(&lib_path, "executorch_no_prim_ops", true).is_ok() { - assert!(link_lib(&lib_path, "executorch_core", true).is_ok()); - } - if !link_lib(&lib_path, "extension_module_static", false).is_ok() { - assert!(link_lib(&lib_path, "extension_module", false).is_ok()); - } - assert!(link_lib(&lib_path, "extension_data_loader", false).is_ok()); - - // Optimized Kernels - if link_lib(&lib_path, "optimized_native_cpu_ops_lib", true).is_ok() { - assert!(link_lib(&lib_path, "optimized_kernels", false).is_ok()); - assert!(link_lib(&lib_path, "portable_kernels", false).is_ok()); - // assert!(link_lib(&lib_path, "cpublas", false).is_ok()); - assert!(link_lib(&lib_path, "eigen_blas", false).is_ok()); - } else { - assert!(link_lib(&lib_path, "portable_ops_lib", true).is_ok()); - assert!(link_lib(&lib_path, "portable_kernels", false).is_ok()); - } - - // Quantized Kernels - if link_lib(&lib_path, "quantized_ops_lib", true).is_ok() { - assert!(link_lib(&lib_path, "quantized_kernels", false).is_ok()); - } - - // Custom Ops - let _ = link_lib(&lib_path, "custom_ops", true); - - // Tensor extension - let _ = link_lib(&lib_path, "extension_tensor", false); - - // Runner Util extension - let _ = link_lib(&lib_path, "extension_runner_util", false); - - // misc. - let _ = link_lib(&lib_path, "cpuinfo", false); - let _ = link_lib(&lib_path, "pthreadpool", false); - - // XNNPACK - if link_lib(&lib_path, "xnnpack_backend", true).is_ok() { - assert!(link_lib(&lib_path, "XNNPACK", false).is_ok()); - let _ = link_lib(&lib_path, "microkernels-prod", false); - } - - // Vulkan - let _ = link_lib(&lib_path, "vulkan_backend", true); - - // QNN - let _ = link_lib(&lib_path, "qnn_executorch_backend", true); - cpp_build::Config::new() .flag("-std=c++17") .build("src/lib.rs"); diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 0000000..ad5b485 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +TARGET_OS=$1 +TARGET_ARCH=$2 +OUT_DIR=$3 + +if [ -z "$TARGET_OS" ] || [ -z "$TARGET_ARCH" ]; then + echo "Usage: $0 " + exit 1 +fi + +if [ "$TARGET_OS" = "windows" ] && [ "$TARGET_ARCH" = "aarch64" ]; then + echo "Cross compiling for Windows on ARM64 is not supported" + exit 1 +fi