Loading CMakeLists.txt +34 −11 Original line number Diff line number Diff line cmake_minimum_required (VERSION 3.21) project (ml_model_embeder CXX) project (ml_model_embedder CXX) #------------------------------------------------------------------------------- # Build Options #------------------------------------------------------------------------------- option (USE_PCH "Enable the use of precompiled headers" ON) option (BUILD_C_BINDING "Build C interface." OFF) option (BUILD_Fortran_BINDING "Build Fortran interface." OFF) #------------------------------------------------------------------------------- # Setup access method. Loading @@ -26,8 +28,8 @@ if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) endif () set_property (CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release Debug MinSizeRel RelWithDebInfo ) Loading Loading @@ -92,20 +94,45 @@ add_dependencies (zip pull_zip) add_subdirectory (source) if (${BUILD_Fortran_BINDING}) set (BUILD_C_BINDING ON CACHE STRING "Build C interface." FORCE) endif () if (${BUILD_C_BINDING}) enable_language (C) add_subdirectory (c_binding) endif () if (${BUILD_Fortran_BINDING}) enable_language (Fortran) add_subdirectory (fortran_binding) endif () #------------------------------------------------------------------------------- # Tool setup #------------------------------------------------------------------------------- macro (add_tool_target target) macro (add_tool_target target lang) add_executable (x${target}) target_sources (x${target} PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${target}.cpp> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${target}.${lang}> ) target_link_libraries (x${target} PUBLIC ml_embeder ml_embedder ) if (${lang} STREQUAL "c") set_source_files_properties (${CMAKE_CURRENT_SOURCE_DIR}/${target}.${lang} PROPERTIES SKIP_PRECOMPILE_HEADERS ON ) endif () if (${USE_PCH} AND ${BUILD_C_BINDING}) target_precompile_headers (x${target} REUSE_FROM ml_c_embedder) endif () endmacro () #------------------------------------------------------------------------------- Loading @@ -116,16 +143,12 @@ enable_testing () #------------------------------------------------------------------------------- # Define macro function to register tests. #------------------------------------------------------------------------------- macro (add_test_target target) add_tool_target (${target}) macro (add_test_target target lang) add_tool_target (${target} ${lang}) add_test (NAME ${target} COMMAND x${target} ) # if (${USE_PCH}) # target_precompile_headers (x${target} REUSE_FROM xml_embeder_test) # endif () endmacro () add_subdirectory (tests) README.md +17 −8 Original line number Diff line number Diff line # ml_model_embeder # ml_model_embedder This is a beginnings of a library to load machine learning models into a C++ library which can be called from C, C++ and Fortran codes. Currently, this only Loading @@ -18,14 +18,14 @@ retrived except for HDF5. The build system is generated using [cmake](https://cmake.org). To build the code first clone the [ml_model_embeder](https://code.ornl.gov/m4c/ml_model_embeder.git) repository. [ml_model_embedder](https://code.ornl.gov/m4c/ml_model_embedder.git) repository. ``` git clone https://code.ornl.gov/m4c/ml_model_embeder.git git clone https://code.ornl.gov/m4c/ml_model_embedder.git ``` The change into the directory git generated and create a build directory then navigate to the build directory. ``` cd ml_model_embeder cd ml_model_embedder mkdir build cd build ``` Loading @@ -36,16 +36,25 @@ cmake ../ make -j ``` Alternatively you can use the `ccmake` command to interactively set build parameters. ### Build Paramaters `CMAKE_BUILD_TYPE` Chooses the build type. Values are - `Release` Optimized builds (Default) - `Debug` Build without optimiation and debug info. - `MinSizeRel` Optimize for executable size. - `RelWithDebInfo` Optimized build with debug info. ## There is an example case which can be run from inside the build directory using the command ``` ./tests/xml_embeder_test ./tests/xml_embedder_test ``` # Todo: - Clean up code into function to build models. - Build C Bindings. - Build Fortran Bindings. - Setup unit tests. c_binding/CMakeLists.txt 0 → 100644 +18 −0 Original line number Diff line number Diff line add_library (ml_c_embedder) target_include_directories (ml_c_embedder PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> ) target_link_libraries (ml_c_embedder PUBLIC ml_embedder ) target_sources (ml_c_embedder PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/ml_c_embedder.cpp> ) target_compile_features (ml_c_embedder PUBLIC c_std_17 ) c_binding/ml_c_embedder.cpp 0 → 100644 +77 −0 Original line number Diff line number Diff line //------------------------------------------------------------------------------ /// @file ml_c_embedder.h /// @brief Implimentation of the c binding library. //------------------------------------------------------------------------------ #include "ml_c_embedder.h" #include <ml_embedder.hpp> //------------------------------------------------------------------------------ /// @@brief Initialize a keras model. /// /// @param[in] filename Path to the keras model. //------------------------------------------------------------------------------ ml_model mlce_init_keras(const char *filename) { return reinterpret_cast<ml_model> (new ml_embedder::keras(std::string(filename))); } //------------------------------------------------------------------------------ /// @brief Finalize a model. /// /// @param[in] m The model model instance. //------------------------------------------------------------------------------ void mlce_finalize(ml_model m) { delete reinterpret_cast<ml_embedder::model *> (m); } //------------------------------------------------------------------------------ /// @brief Get a the input shape. /// /// @param[in] m The model model instance. /// @param[out] s The number of elements in the shape. /// @returns The input shape array. //------------------------------------------------------------------------------ int *mlce_in_shape(ml_model m, size_t *s) { ml_embedder::model *model = reinterpret_cast<ml_embedder::model *> (m); s[0] = model->input_shape.size(); return reinterpret_cast<int *> (model->input_shape.data()); } //------------------------------------------------------------------------------ /// @brief Get a the output shape. /// /// @param[in] m The model model instance. /// @param[out] s The number of elements in the shape. /// @returns The output shape array. //------------------------------------------------------------------------------ int *mlce_out_shape(ml_model m, size_t *s) { ml_embedder::model *model = reinterpret_cast<ml_embedder::model *> (m); s[0] = model->input_shape.size(); return reinterpret_cast<int *> (model->output_shape.data()); } //------------------------------------------------------------------------------ /// @brief Run a model. /// /// @note The user is require to allocate an output buffer of the correct size. /// /// @param[in] m The model model instance. /// @param[in] in The input buffer. /// @param[in] out The output buffer. /// @param[in] batch_size The size of a batch. /// @param[in] input_size The size of a batch. //------------------------------------------------------------------------------ void mlce_run_float(ml_model m, void *in, void *out, const int batch_size) { ml_embedder::model *model = reinterpret_cast<ml_embedder::model *> (m); mlx::core::SmallVector<int> shape; shape.push_back(batch_size); for (auto i : model->input_shape) { shape.push_back(i); } mlx::core::array input = mlx::core::array((float *)in, shape, mlx::core::float32); mlx::core::array y = model->func({input})[0]; y.eval(); std::memcpy(out, y.data<float> (), y.nbytes()); } c_binding/ml_c_embedder.h 0 → 100644 +69 −0 Original line number Diff line number Diff line //------------------------------------------------------------------------------ /// @file ml_c_embedder.h /// @brief Header file for the c binding library. //------------------------------------------------------------------------------ #ifndef ml_c_embedder_h #define ml_c_embedder_h #ifndef __cplusplus #include <stddef.h> #endif #ifdef __cplusplus extern "C" { #endif /// ml_model type for C interface. typedef void *ml_model; //------------------------------------------------------------------------------ /// @brief Initialize a keras model. /// /// @param[in] filename Path to the keras model. //------------------------------------------------------------------------------ ml_model mlce_init_keras(const char *filename); //------------------------------------------------------------------------------ /// @brief Finalize a model. /// /// @param[in] m The model model instance. //------------------------------------------------------------------------------ void mlce_finalize(ml_model m); //------------------------------------------------------------------------------ /// @brief Get a the input shape. /// /// @param[in] m The model model instance. /// @param[out] s The number of elements in the shape. /// @returns The input shape array. //------------------------------------------------------------------------------ int *mlce_in_shape(ml_model m, size_t *s); //------------------------------------------------------------------------------ /// @brief Get a the output shape. /// /// @param[in] m The model model instance. /// @param[out] s The number of elements in the shape. /// @returns The output shape array. //------------------------------------------------------------------------------ int *mlce_out_shape(ml_model m, size_t *s); //------------------------------------------------------------------------------ /// @brief Run a model with float inputs. /// /// @note The user is required to allocate an output buffer of the correct /// size. /// /// @param[in] m The model model instance. /// @param[in] in The input buffer. /// @param[in] out The output buffer. /// @param[in] batch_size The size of a batch. //------------------------------------------------------------------------------ void mlce_run_float(ml_model m, void *in, void *out, const int batch_size); #ifdef __cplusplus } #endif #endif /* ml_c_embedder_h */ Loading
CMakeLists.txt +34 −11 Original line number Diff line number Diff line cmake_minimum_required (VERSION 3.21) project (ml_model_embeder CXX) project (ml_model_embedder CXX) #------------------------------------------------------------------------------- # Build Options #------------------------------------------------------------------------------- option (USE_PCH "Enable the use of precompiled headers" ON) option (BUILD_C_BINDING "Build C interface." OFF) option (BUILD_Fortran_BINDING "Build Fortran interface." OFF) #------------------------------------------------------------------------------- # Setup access method. Loading @@ -26,8 +28,8 @@ if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) endif () set_property (CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release Debug MinSizeRel RelWithDebInfo ) Loading Loading @@ -92,20 +94,45 @@ add_dependencies (zip pull_zip) add_subdirectory (source) if (${BUILD_Fortran_BINDING}) set (BUILD_C_BINDING ON CACHE STRING "Build C interface." FORCE) endif () if (${BUILD_C_BINDING}) enable_language (C) add_subdirectory (c_binding) endif () if (${BUILD_Fortran_BINDING}) enable_language (Fortran) add_subdirectory (fortran_binding) endif () #------------------------------------------------------------------------------- # Tool setup #------------------------------------------------------------------------------- macro (add_tool_target target) macro (add_tool_target target lang) add_executable (x${target}) target_sources (x${target} PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${target}.cpp> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${target}.${lang}> ) target_link_libraries (x${target} PUBLIC ml_embeder ml_embedder ) if (${lang} STREQUAL "c") set_source_files_properties (${CMAKE_CURRENT_SOURCE_DIR}/${target}.${lang} PROPERTIES SKIP_PRECOMPILE_HEADERS ON ) endif () if (${USE_PCH} AND ${BUILD_C_BINDING}) target_precompile_headers (x${target} REUSE_FROM ml_c_embedder) endif () endmacro () #------------------------------------------------------------------------------- Loading @@ -116,16 +143,12 @@ enable_testing () #------------------------------------------------------------------------------- # Define macro function to register tests. #------------------------------------------------------------------------------- macro (add_test_target target) add_tool_target (${target}) macro (add_test_target target lang) add_tool_target (${target} ${lang}) add_test (NAME ${target} COMMAND x${target} ) # if (${USE_PCH}) # target_precompile_headers (x${target} REUSE_FROM xml_embeder_test) # endif () endmacro () add_subdirectory (tests)
README.md +17 −8 Original line number Diff line number Diff line # ml_model_embeder # ml_model_embedder This is a beginnings of a library to load machine learning models into a C++ library which can be called from C, C++ and Fortran codes. Currently, this only Loading @@ -18,14 +18,14 @@ retrived except for HDF5. The build system is generated using [cmake](https://cmake.org). To build the code first clone the [ml_model_embeder](https://code.ornl.gov/m4c/ml_model_embeder.git) repository. [ml_model_embedder](https://code.ornl.gov/m4c/ml_model_embedder.git) repository. ``` git clone https://code.ornl.gov/m4c/ml_model_embeder.git git clone https://code.ornl.gov/m4c/ml_model_embedder.git ``` The change into the directory git generated and create a build directory then navigate to the build directory. ``` cd ml_model_embeder cd ml_model_embedder mkdir build cd build ``` Loading @@ -36,16 +36,25 @@ cmake ../ make -j ``` Alternatively you can use the `ccmake` command to interactively set build parameters. ### Build Paramaters `CMAKE_BUILD_TYPE` Chooses the build type. Values are - `Release` Optimized builds (Default) - `Debug` Build without optimiation and debug info. - `MinSizeRel` Optimize for executable size. - `RelWithDebInfo` Optimized build with debug info. ## There is an example case which can be run from inside the build directory using the command ``` ./tests/xml_embeder_test ./tests/xml_embedder_test ``` # Todo: - Clean up code into function to build models. - Build C Bindings. - Build Fortran Bindings. - Setup unit tests.
c_binding/CMakeLists.txt 0 → 100644 +18 −0 Original line number Diff line number Diff line add_library (ml_c_embedder) target_include_directories (ml_c_embedder PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> ) target_link_libraries (ml_c_embedder PUBLIC ml_embedder ) target_sources (ml_c_embedder PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/ml_c_embedder.cpp> ) target_compile_features (ml_c_embedder PUBLIC c_std_17 )
c_binding/ml_c_embedder.cpp 0 → 100644 +77 −0 Original line number Diff line number Diff line //------------------------------------------------------------------------------ /// @file ml_c_embedder.h /// @brief Implimentation of the c binding library. //------------------------------------------------------------------------------ #include "ml_c_embedder.h" #include <ml_embedder.hpp> //------------------------------------------------------------------------------ /// @@brief Initialize a keras model. /// /// @param[in] filename Path to the keras model. //------------------------------------------------------------------------------ ml_model mlce_init_keras(const char *filename) { return reinterpret_cast<ml_model> (new ml_embedder::keras(std::string(filename))); } //------------------------------------------------------------------------------ /// @brief Finalize a model. /// /// @param[in] m The model model instance. //------------------------------------------------------------------------------ void mlce_finalize(ml_model m) { delete reinterpret_cast<ml_embedder::model *> (m); } //------------------------------------------------------------------------------ /// @brief Get a the input shape. /// /// @param[in] m The model model instance. /// @param[out] s The number of elements in the shape. /// @returns The input shape array. //------------------------------------------------------------------------------ int *mlce_in_shape(ml_model m, size_t *s) { ml_embedder::model *model = reinterpret_cast<ml_embedder::model *> (m); s[0] = model->input_shape.size(); return reinterpret_cast<int *> (model->input_shape.data()); } //------------------------------------------------------------------------------ /// @brief Get a the output shape. /// /// @param[in] m The model model instance. /// @param[out] s The number of elements in the shape. /// @returns The output shape array. //------------------------------------------------------------------------------ int *mlce_out_shape(ml_model m, size_t *s) { ml_embedder::model *model = reinterpret_cast<ml_embedder::model *> (m); s[0] = model->input_shape.size(); return reinterpret_cast<int *> (model->output_shape.data()); } //------------------------------------------------------------------------------ /// @brief Run a model. /// /// @note The user is require to allocate an output buffer of the correct size. /// /// @param[in] m The model model instance. /// @param[in] in The input buffer. /// @param[in] out The output buffer. /// @param[in] batch_size The size of a batch. /// @param[in] input_size The size of a batch. //------------------------------------------------------------------------------ void mlce_run_float(ml_model m, void *in, void *out, const int batch_size) { ml_embedder::model *model = reinterpret_cast<ml_embedder::model *> (m); mlx::core::SmallVector<int> shape; shape.push_back(batch_size); for (auto i : model->input_shape) { shape.push_back(i); } mlx::core::array input = mlx::core::array((float *)in, shape, mlx::core::float32); mlx::core::array y = model->func({input})[0]; y.eval(); std::memcpy(out, y.data<float> (), y.nbytes()); }
c_binding/ml_c_embedder.h 0 → 100644 +69 −0 Original line number Diff line number Diff line //------------------------------------------------------------------------------ /// @file ml_c_embedder.h /// @brief Header file for the c binding library. //------------------------------------------------------------------------------ #ifndef ml_c_embedder_h #define ml_c_embedder_h #ifndef __cplusplus #include <stddef.h> #endif #ifdef __cplusplus extern "C" { #endif /// ml_model type for C interface. typedef void *ml_model; //------------------------------------------------------------------------------ /// @brief Initialize a keras model. /// /// @param[in] filename Path to the keras model. //------------------------------------------------------------------------------ ml_model mlce_init_keras(const char *filename); //------------------------------------------------------------------------------ /// @brief Finalize a model. /// /// @param[in] m The model model instance. //------------------------------------------------------------------------------ void mlce_finalize(ml_model m); //------------------------------------------------------------------------------ /// @brief Get a the input shape. /// /// @param[in] m The model model instance. /// @param[out] s The number of elements in the shape. /// @returns The input shape array. //------------------------------------------------------------------------------ int *mlce_in_shape(ml_model m, size_t *s); //------------------------------------------------------------------------------ /// @brief Get a the output shape. /// /// @param[in] m The model model instance. /// @param[out] s The number of elements in the shape. /// @returns The output shape array. //------------------------------------------------------------------------------ int *mlce_out_shape(ml_model m, size_t *s); //------------------------------------------------------------------------------ /// @brief Run a model with float inputs. /// /// @note The user is required to allocate an output buffer of the correct /// size. /// /// @param[in] m The model model instance. /// @param[in] in The input buffer. /// @param[in] out The output buffer. /// @param[in] batch_size The size of a batch. //------------------------------------------------------------------------------ void mlce_run_float(ml_model m, void *in, void *out, const int batch_size); #ifdef __cplusplus } #endif #endif /* ml_c_embedder_h */