├── .clang-format ├── .gitmodules ├── include ├── CMakeLists.txt ├── tensorflow_module.h ├── tensorflowlite_module.h ├── tensorflowlite_base.h ├── wasmedge │ ├── wasmedge-tensorflow.h │ └── wasmedge-tensorflowlite.h ├── tensorflowfake_module.h ├── tensorflow_base.h ├── tensorflowlite_func.h ├── tensorflow_func.h └── tensorflowfake_func.h ├── .CurrentChangelog.md ├── lib ├── wasmedge-tensorflow.cpp ├── wasmedge-tensorflowlite.cpp ├── tensorflowlite_module.cpp ├── tensorflow_module.cpp ├── tensorflowlite_func.cpp ├── CMakeLists.txt └── tensorflow_func.cpp ├── .github ├── scripts │ └── clang-format.sh └── workflows │ ├── linter.yml │ ├── build.yml │ └── release.yml ├── LICENSE.spdx ├── .clang-tidy ├── .gitignore ├── README.md ├── CMakeLists.txt └── Changelog.md /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | IndentWidth: 2 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "utils/WasmEdge-tensorflow-deps"] 2 | path = utils/WasmEdge-tensorflow-deps 3 | url = https://github.com/second-state/WasmEdge-tensorflow-deps.git 4 | branch = 0.8.0 -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | configure_file(wasmedge/wasmedge-tensorflow.h wasmedge/wasmedge-tensorflow.h) 4 | configure_file(wasmedge/wasmedge-tensorflowlite.h wasmedge/wasmedge-tensorflowlite.h) 5 | -------------------------------------------------------------------------------- /.CurrentChangelog.md: -------------------------------------------------------------------------------- 1 | ### 0.12.1 (2023-05-12) 2 | 3 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 4 | Please refer to the [WasmEdge 0.12.1](https://github.com/WasmEdge/WasmEdge/releases/tag/0.12.1) for more details. 5 | 6 | Features: 7 | 8 | * Update the `WasmEdge` dependency to `0.12.1`. 9 | -------------------------------------------------------------------------------- /include/tensorflow_module.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #pragma once 5 | 6 | #include "runtime/instance/module.h" 7 | 8 | namespace WasmEdge { 9 | namespace Host { 10 | 11 | class WasmEdgeTensorflowModule : public Runtime::Instance::ModuleInstance { 12 | public: 13 | WasmEdgeTensorflowModule(); 14 | ~WasmEdgeTensorflowModule() = default; 15 | }; 16 | 17 | } // namespace Host 18 | } // namespace WasmEdge 19 | -------------------------------------------------------------------------------- /include/tensorflowlite_module.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #pragma once 5 | 6 | #include "runtime/instance/module.h" 7 | 8 | namespace WasmEdge { 9 | namespace Host { 10 | 11 | class WasmEdgeTensorflowLiteModule : public Runtime::Instance::ModuleInstance { 12 | public: 13 | WasmEdgeTensorflowLiteModule(); 14 | ~WasmEdgeTensorflowLiteModule() = default; 15 | }; 16 | 17 | } // namespace Host 18 | } // namespace WasmEdge 19 | -------------------------------------------------------------------------------- /lib/wasmedge-tensorflow.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #include "wasmedge/wasmedge-tensorflow.h" 5 | #include "tensorflow_module.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | WasmEdge_ModuleInstanceContext *WasmEdge_Tensorflow_ModuleInstanceCreate() { 12 | return reinterpret_cast( 13 | new WasmEdge::Host::WasmEdgeTensorflowModule()); 14 | } 15 | 16 | #ifdef __cplusplus 17 | } // extern "C" 18 | #endif 19 | -------------------------------------------------------------------------------- /.github/scripts/clang-format.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | # Usage: $0 clang-format(version >= 10.0) 4 | # $ bash clang-format.sh `which clang-format` 5 | 6 | lint() { 7 | local targets="include lib" 8 | local clang_format="${1}" 9 | 10 | if [ "$#" -ne 1 ]; then 11 | echo "please provide clang-format command. Usage ${0} `which clang-format`" 12 | exit 1 13 | fi 14 | 15 | if [ ! -f "${clang_format}" ]; then 16 | echo "clang-format not found. Please install clang-format first" 17 | exit 1 18 | fi 19 | 20 | find ${targets} -type f -iname *.[ch] -o -iname *.cpp -o -iname *.[ch]xx \ 21 | | xargs -n1 ${clang_format} -i -style=file -Werror --dry-run 22 | 23 | exit $? 24 | } 25 | 26 | lint $@ 27 | -------------------------------------------------------------------------------- /.github/workflows/linter.yml: -------------------------------------------------------------------------------- 1 | name: Clang-Format 2 | 3 | concurrency: 4 | group: clang-format-${{ github.head_ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | push: 9 | branches: 10 | - master 11 | paths-ignore: 12 | - 'docs/**' 13 | - '**.md' 14 | pull_request: 15 | branches: 16 | - master 17 | paths-ignore: 18 | - 'docs/**' 19 | - '**.md' 20 | 21 | jobs: 22 | lint: 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v3 26 | with: 27 | fetch-depth: 0 28 | - name: Install clang-format-15 29 | run: | 30 | sudo apt update 31 | sudo apt install clang-format-15 32 | - name: Run clang-format 33 | run: | 34 | bash ./.github/scripts/clang-format.sh `which clang-format-15` 35 | -------------------------------------------------------------------------------- /LICENSE.spdx: -------------------------------------------------------------------------------- 1 | ## This file states the license of this package and possibly its subpackages 2 | ## in machine and human readable format. The PackageName refers to the package 3 | ## whose license is defined by PackageLicenseConcluded. 4 | ## For more information about this file format visit the SPDX website at 5 | ## https://spdx.org 6 | 7 | SPDXVersion: SPDX-2.1 8 | DataLicense: CC0-1.0 9 | SPDXID: SPDXRef-DOCUMENT 10 | DocumentNamespace: https://secondstate.io/ssvm 11 | DocumentName: LICENSE.spdx 12 | 13 | Creator: Organization: Second State INC (contact@secondstate.io) 14 | 15 | ## Package Information 16 | PackageName: wasmedge-tensorflow 17 | SPDXID: SPDXRef-wasmedge-tensorflow 18 | PackageOriginator: Organization: Second State INC (contact@secondstate.io) 19 | PackageLicenseDeclared: Apache-2.0 20 | FilesAnalyzed: false 21 | -------------------------------------------------------------------------------- /lib/wasmedge-tensorflowlite.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #include "wasmedge/wasmedge-tensorflowlite.h" 5 | #include "tensorflowfake_module.h" 6 | #include "tensorflowlite_module.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | WasmEdge_ModuleInstanceContext *WasmEdge_TensorflowLite_ModuleInstanceCreate() { 13 | return reinterpret_cast( 14 | new WasmEdge::Host::WasmEdgeTensorflowLiteModule()); 15 | } 16 | 17 | WasmEdge_ModuleInstanceContext * 18 | WasmEdge_Tensorflow_ModuleInstanceCreateDummy() { 19 | return reinterpret_cast( 20 | new WasmEdge::Host::WasmEdgeTensorflowFakeModule()); 21 | } 22 | 23 | #ifdef __cplusplus 24 | } // extern "C" 25 | #endif 26 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,readability-identifier-naming' 2 | CheckOptions: 3 | - key: readability-identifier-naming.ClassCase 4 | value: CamelCase 5 | - key: readability-identifier-naming.EnumCase 6 | value: CamelCase 7 | - key: readability-identifier-naming.FunctionCase 8 | value: camelBack 9 | - key: readability-identifier-naming.MemberCase 10 | value: CamelCase 11 | - key: readability-identifier-naming.ParameterCase 12 | value: CamelCase 13 | - key: readability-identifier-naming.UnionCase 14 | value: CamelCase 15 | - key: readability-identifier-naming.VariableCase 16 | value: CamelCase 17 | 18 | -------------------------------------------------------------------------------- /include/tensorflowlite_base.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "tensorflow/lite/c/c_api.h" 11 | 12 | #include "common/errcode.h" 13 | #include "runtime/callingframe.h" 14 | #include "runtime/hostfunc.h" 15 | 16 | namespace WasmEdge { 17 | namespace Host { 18 | 19 | struct WasmEdgeTensorflowLiteContext { 20 | WasmEdgeTensorflowLiteContext() = default; 21 | ~WasmEdgeTensorflowLiteContext() { 22 | if (Interp) { 23 | TfLiteInterpreterDelete(Interp); 24 | } 25 | } 26 | TfLiteInterpreter *Interp = nullptr; 27 | }; 28 | 29 | template 30 | class WasmEdgeTensorflowLite : public Runtime::HostFunction { 31 | public: 32 | WasmEdgeTensorflowLite() : Runtime::HostFunction(0) {} 33 | }; 34 | 35 | } // namespace Host 36 | } // namespace WasmEdge 37 | -------------------------------------------------------------------------------- /include/wasmedge/wasmedge-tensorflow.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | //===-- WasmEdge-tensorflow/wasmedge-tensorflow.h - C API -----------------===// 5 | // 6 | // Part of the WasmEdge Project. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | /// 10 | /// \file 11 | /// This file contains the function declarations of WasmEdge Tensorflow C API. 12 | /// 13 | //===----------------------------------------------------------------------===// 14 | 15 | #ifndef __WASMEDGE_TENSORFLOW_C_API_H__ 16 | #define __WASMEDGE_TENSORFLOW_C_API_H__ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | // Need to install the WasmEdge C library first. 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /// Creation of the WasmEdge_ModuleInstanceContext for the wasmedge_tensorflow 31 | /// host functions. 32 | /// 33 | /// The caller owns the object and should call `WasmEdge_ModuleInstanceDelete` 34 | /// to destroy it. 35 | /// 36 | /// \returns pointer to context, NULL if failed. 37 | WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * 38 | WasmEdge_Tensorflow_ModuleInstanceCreate(); 39 | 40 | #ifdef __cplusplus 41 | } // extern "C" 42 | #endif 43 | 44 | #endif // __WASMEDGE_TENSORFLOW_C_API_H__ 45 | -------------------------------------------------------------------------------- /lib/tensorflowlite_module.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #include "tensorflowlite_module.h" 5 | #include "tensorflowlite_func.h" 6 | 7 | #include 8 | 9 | namespace WasmEdge { 10 | namespace Host { 11 | 12 | WasmEdgeTensorflowLiteModule::WasmEdgeTensorflowLiteModule() 13 | : Runtime::Instance::ModuleInstance("wasmedge_tensorflowlite") { 14 | addHostFunc("wasmedge_tensorflowlite_create_session", 15 | std::make_unique()); 16 | addHostFunc("wasmedge_tensorflowlite_delete_session", 17 | std::make_unique()); 18 | addHostFunc("wasmedge_tensorflowlite_run_session", 19 | std::make_unique()); 20 | addHostFunc("wasmedge_tensorflowlite_get_output_tensor", 21 | std::make_unique()); 22 | addHostFunc("wasmedge_tensorflowlite_get_tensor_len", 23 | std::make_unique()); 24 | addHostFunc("wasmedge_tensorflowlite_get_tensor_data", 25 | std::make_unique()); 26 | addHostFunc("wasmedge_tensorflowlite_append_input", 27 | std::make_unique()); 28 | } 29 | 30 | } // namespace Host 31 | } // namespace WasmEdge 32 | -------------------------------------------------------------------------------- /lib/tensorflow_module.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #include "tensorflow_module.h" 5 | #include "tensorflow_func.h" 6 | 7 | #include 8 | 9 | namespace WasmEdge { 10 | namespace Host { 11 | 12 | WasmEdgeTensorflowModule::WasmEdgeTensorflowModule() 13 | : Runtime::Instance::ModuleInstance("wasmedge_tensorflow") { 14 | addHostFunc("wasmedge_tensorflow_create_session", 15 | std::make_unique()); 16 | addHostFunc("wasmedge_tensorflow_delete_session", 17 | std::make_unique()); 18 | addHostFunc("wasmedge_tensorflow_run_session", 19 | std::make_unique()); 20 | addHostFunc("wasmedge_tensorflow_get_output_tensor", 21 | std::make_unique()); 22 | addHostFunc("wasmedge_tensorflow_get_tensor_len", 23 | std::make_unique()); 24 | addHostFunc("wasmedge_tensorflow_get_tensor_data", 25 | std::make_unique()); 26 | addHostFunc("wasmedge_tensorflow_append_input", 27 | std::make_unique()); 28 | addHostFunc("wasmedge_tensorflow_append_output", 29 | std::make_unique()); 30 | addHostFunc("wasmedge_tensorflow_clear_input", 31 | std::make_unique()); 32 | addHostFunc("wasmedge_tensorflow_clear_output", 33 | std::make_unique()); 34 | } 35 | 36 | } // namespace Host 37 | } // namespace WasmEdge 38 | -------------------------------------------------------------------------------- /include/tensorflowfake_module.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #pragma once 5 | 6 | #include "runtime/instance/module.h" 7 | #include "tensorflowfake_func.h" 8 | 9 | namespace WasmEdge { 10 | namespace Host { 11 | 12 | class WasmEdgeTensorflowFakeModule : public Runtime::Instance::ModuleInstance { 13 | public: 14 | WasmEdgeTensorflowFakeModule() 15 | : Runtime::Instance::ModuleInstance("wasmedge_tensorflow") { 16 | addHostFunc("wasmedge_tensorflow_create_session", 17 | std::make_unique()); 18 | addHostFunc("wasmedge_tensorflow_delete_session", 19 | std::make_unique()); 20 | addHostFunc("wasmedge_tensorflow_run_session", 21 | std::make_unique()); 22 | addHostFunc("wasmedge_tensorflow_get_output_tensor", 23 | std::make_unique()); 24 | addHostFunc("wasmedge_tensorflow_get_tensor_len", 25 | std::make_unique()); 26 | addHostFunc("wasmedge_tensorflow_get_tensor_data", 27 | std::make_unique()); 28 | addHostFunc("wasmedge_tensorflow_append_input", 29 | std::make_unique()); 30 | addHostFunc("wasmedge_tensorflow_append_output", 31 | std::make_unique()); 32 | addHostFunc("wasmedge_tensorflow_clear_input", 33 | std::make_unique()); 34 | addHostFunc("wasmedge_tensorflow_clear_output", 35 | std::make_unique()); 36 | } 37 | ~WasmEdgeTensorflowFakeModule() = default; 38 | }; 39 | 40 | } // namespace Host 41 | } // namespace WasmEdge 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #==============================================================================# 2 | # This file specifies intentionally untracked files that git should ignore. 3 | # See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html 4 | # 5 | # This file is intentionally different from the output of `git svn show-ignore`, 6 | # as most of those are useless. 7 | #==============================================================================# 8 | 9 | #==============================================================================# 10 | # File extensions to be ignored anywhere in the tree. 11 | #==============================================================================# 12 | # Temp files created by most text editors. 13 | *~ 14 | # Merge files created by git. 15 | *.orig 16 | # Byte compiled python modules. 17 | *.pyc 18 | # vim swap files 19 | .*.sw? 20 | .sw? 21 | #OS X specific files. 22 | .DS_store 23 | 24 | # Nested build directory 25 | /build 26 | /target 27 | 28 | #==============================================================================# 29 | # Explicit files to ignore (only matches one). 30 | #==============================================================================# 31 | # Various tag programs 32 | /tags 33 | /TAGS 34 | /GPATH 35 | /GRTAGS 36 | /GSYMS 37 | /GTAGS 38 | .gitusers 39 | autom4te.cache 40 | cscope.files 41 | cscope.out 42 | Cargo.lock 43 | autoconf/aclocal.m4 44 | autoconf/autom4te.cache 45 | /compile_commands.json 46 | # Visual Studio built-in CMake configuration 47 | /CMakeSettings.json 48 | # CLion project configuration 49 | /.idea 50 | 51 | #==============================================================================# 52 | # Directories to ignore (do not add trailing '/'s, they skip symlinks). 53 | #==============================================================================# 54 | # External projects that are tracked independently. 55 | projects/* 56 | !projects/*.* 57 | !projects/Makefile 58 | runtimes/* 59 | !runtimes/*.* 60 | # Sphinx build tree, if building in-source dir. 61 | docs/_build 62 | # VS2017 and VSCode config files. 63 | .vscode 64 | .vs 65 | # clangd index 66 | .clangd 67 | -------------------------------------------------------------------------------- /include/tensorflow_base.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "tensorflow/c/c_api.h" 11 | 12 | #include "common/errcode.h" 13 | #include "runtime/callingframe.h" 14 | #include "runtime/hostfunc.h" 15 | 16 | namespace WasmEdge { 17 | namespace Host { 18 | 19 | struct WasmEdgeTensorflowContext { 20 | WasmEdgeTensorflowContext() { Stat = TF_NewStatus(); } 21 | ~WasmEdgeTensorflowContext() { 22 | if (GraphOpts) { 23 | TF_DeleteImportGraphDefOptions(GraphOpts); 24 | } 25 | if (Buffer) { 26 | TF_DeleteBuffer(Buffer); 27 | } 28 | if (Graph) { 29 | TF_DeleteGraph(Graph); 30 | } 31 | if (SessionOpts) { 32 | TF_DeleteSessionOptions(SessionOpts); 33 | } 34 | if (Session) { 35 | TF_CloseSession(Session, Stat); 36 | TF_DeleteSession(Session, Stat); 37 | } 38 | TF_DeleteStatus(Stat); 39 | for (uint32_t I = 0; I < InputTensors.size(); ++I) { 40 | if (InputTensors[I]) { 41 | TF_DeleteTensor(InputTensors[I]); 42 | } 43 | } 44 | for (uint32_t I = 0; I < OutputTensors.size(); ++I) { 45 | if (OutputTensors[I]) { 46 | TF_DeleteTensor(OutputTensors[I]); 47 | } 48 | } 49 | } 50 | 51 | TF_Status *Stat; 52 | TF_ImportGraphDefOptions *GraphOpts = nullptr; 53 | TF_Buffer *Buffer = nullptr; 54 | TF_Graph *Graph = nullptr; 55 | TF_SessionOptions *SessionOpts = nullptr; 56 | TF_Session *Session = nullptr; 57 | std::vector> InputNames; 58 | std::vector> OutputNames; 59 | std::vector Inputs; 60 | std::vector Outputs; 61 | std::vector InputTensors; 62 | std::vector OutputTensors; 63 | }; 64 | 65 | template 66 | class WasmEdgeTensorflow : public Runtime::HostFunction { 67 | public: 68 | WasmEdgeTensorflow() : Runtime::HostFunction(0) {} 69 | }; 70 | 71 | } // namespace Host 72 | } // namespace WasmEdge 73 | -------------------------------------------------------------------------------- /include/wasmedge/wasmedge-tensorflowlite.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | //===-- WasmEdge-tensorflow/wasmedge-tensorflowlite.h - C API -------------===// 5 | // 6 | // Part of the WasmEdge Project. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | /// 10 | /// \file 11 | /// This file contains the function declarations of WasmEdge Tensorflow lite C 12 | /// API. 13 | /// 14 | //===----------------------------------------------------------------------===// 15 | 16 | #ifndef __WASMEDGE_TENSORFLOWLITE_C_API_H__ 17 | #define __WASMEDGE_TENSORFLOWLITE_C_API_H__ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | // Need to install the WasmEdge C library first. 25 | #include 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | /// Creation of the WasmEdge_ModuleInstanceContext for the 32 | /// wasmedge_tensorflowlite host functions. 33 | /// 34 | /// The caller owns the object and should call `WasmEdge_ModuleInstanceDelete` 35 | /// to destroy it. 36 | /// 37 | /// \returns pointer to context, NULL if failed. 38 | WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * 39 | WasmEdge_TensorflowLite_ModuleInstanceCreate(); 40 | 41 | /// Creation of the WasmEdge_ModuleInstanceContext for the wasmedge_tensorflow 42 | /// fake host functions. 43 | /// 44 | /// This function will create a dummy wasmedge_tensorflow module instance which 45 | /// the implementation of host functions are all empty. The dummy module 46 | /// instance is used by the runners which only link to the tensorflow-lite 47 | /// shared library and need to accept WASM which want to import 48 | /// wasmedge_tensorflow host functions. 49 | /// 50 | /// The caller owns the object and should call `WasmEdge_ModuleInstanceDelete` 51 | /// to destroy it. 52 | /// 53 | /// \returns pointer to context, NULL if failed. 54 | WASMEDGE_CAPI_EXPORT extern WasmEdge_ModuleInstanceContext * 55 | WasmEdge_Tensorflow_ModuleInstanceCreateDummy(); 56 | 57 | #ifdef __cplusplus 58 | } // extern "C" 59 | #endif 60 | 61 | #endif // __WASMEDGE_TENSORFLOWLITE_C_API_H__ 62 | -------------------------------------------------------------------------------- /include/tensorflowlite_func.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #pragma once 5 | 6 | #include "tensorflowlite_base.h" 7 | 8 | namespace WasmEdge { 9 | namespace Host { 10 | 11 | class WasmEdgeTensorflowLiteCreateSession 12 | : public WasmEdgeTensorflowLite { 13 | public: 14 | Expect body(const Runtime::CallingFrame &CallFrame, 15 | uint32_t ModBufPtr, uint32_t ModBufLen); 16 | }; 17 | 18 | class WasmEdgeTensorflowLiteDeleteSession 19 | : public WasmEdgeTensorflowLite { 20 | public: 21 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt); 22 | }; 23 | 24 | class WasmEdgeTensorflowLiteRunSession 25 | : public WasmEdgeTensorflowLite { 26 | public: 27 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt); 28 | }; 29 | 30 | class WasmEdgeTensorflowLiteGetOutputTensor 31 | : public WasmEdgeTensorflowLite { 32 | public: 33 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt, 34 | uint32_t OutputPtr, uint32_t OutputLen); 35 | }; 36 | 37 | class WasmEdgeTensorflowLiteGetTensorLen 38 | : public WasmEdgeTensorflowLite { 39 | public: 40 | Expect body(const Runtime::CallingFrame &CallFrame, 41 | uint64_t Tensor); 42 | }; 43 | 44 | class WasmEdgeTensorflowLiteGetTensorData 45 | : public WasmEdgeTensorflowLite { 46 | public: 47 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Tensor, 48 | uint32_t BufPtr); 49 | }; 50 | 51 | class WasmEdgeTensorflowLiteAppendInput 52 | : public WasmEdgeTensorflowLite { 53 | public: 54 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt, 55 | uint32_t InputPtr, uint32_t InputLen, uint32_t TensorBufPtr, 56 | uint32_t TensorBufLen); 57 | }; 58 | 59 | } // namespace Host 60 | } // namespace WasmEdge 61 | -------------------------------------------------------------------------------- /include/tensorflow_func.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #pragma once 5 | 6 | #include "tensorflow_base.h" 7 | 8 | namespace WasmEdge { 9 | namespace Host { 10 | 11 | class WasmEdgeTensorflowCreateSession 12 | : public WasmEdgeTensorflow { 13 | public: 14 | Expect body(const Runtime::CallingFrame &CallFrame, 15 | uint32_t ModBufPtr, uint32_t ModBufLen); 16 | }; 17 | 18 | class WasmEdgeTensorflowDeleteSession 19 | : public WasmEdgeTensorflow { 20 | public: 21 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt); 22 | }; 23 | 24 | class WasmEdgeTensorflowRunSession 25 | : public WasmEdgeTensorflow { 26 | public: 27 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt); 28 | }; 29 | 30 | class WasmEdgeTensorflowGetOutputTensor 31 | : public WasmEdgeTensorflow { 32 | public: 33 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt, 34 | uint32_t OutputPtr, uint32_t OutputLen, uint32_t Idx); 35 | }; 36 | 37 | class WasmEdgeTensorflowGetTensorLen 38 | : public WasmEdgeTensorflow { 39 | public: 40 | Expect body(const Runtime::CallingFrame &CallFrame, 41 | uint64_t Tensor); 42 | }; 43 | 44 | class WasmEdgeTensorflowGetTensorData 45 | : public WasmEdgeTensorflow { 46 | public: 47 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Tensor, 48 | uint32_t BufPtr); 49 | }; 50 | 51 | class WasmEdgeTensorflowAppendInput 52 | : public WasmEdgeTensorflow { 53 | public: 54 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt, 55 | uint32_t InputPtr, uint32_t InputLen, uint32_t Idx, 56 | uint32_t DimPtr, uint32_t DimCnt, uint32_t DataType, 57 | uint32_t TensorBufPtr, uint32_t TensorBufLen); 58 | }; 59 | 60 | class WasmEdgeTensorflowAppendOutput 61 | : public WasmEdgeTensorflow { 62 | public: 63 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt, 64 | uint32_t OutputPtr, uint32_t OutputLen, uint32_t Idx); 65 | }; 66 | 67 | class WasmEdgeTensorflowClearInput 68 | : public WasmEdgeTensorflow { 69 | public: 70 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt); 71 | }; 72 | 73 | class WasmEdgeTensorflowClearOutput 74 | : public WasmEdgeTensorflow { 75 | public: 76 | Expect body(const Runtime::CallingFrame &CallFrame, uint64_t Cxt); 77 | }; 78 | 79 | } // namespace Host 80 | } // namespace WasmEdge 81 | -------------------------------------------------------------------------------- /include/tensorflowfake_func.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #pragma once 5 | 6 | #include "common/errcode.h" 7 | #include "runtime/callingframe.h" 8 | #include "runtime/hostfunc.h" 9 | 10 | namespace WasmEdge { 11 | namespace Host { 12 | 13 | template 14 | class WasmEdgeTensorflowFake : public Runtime::HostFunction { 15 | public: 16 | WasmEdgeTensorflowFake() : Runtime::HostFunction(0) {} 17 | }; 18 | 19 | class WasmEdgeTensorflowFakeCreateSession 20 | : public WasmEdgeTensorflowFake { 21 | public: 22 | Expect body(const Runtime::CallingFrame &, uint32_t ModBufPtr, 23 | uint32_t ModBufLen) { 24 | return 0; 25 | } 26 | }; 27 | 28 | class WasmEdgeTensorflowFakeDeleteSession 29 | : public WasmEdgeTensorflowFake { 30 | public: 31 | Expect body(const Runtime::CallingFrame &, uint64_t Cxt) { return {}; } 32 | }; 33 | 34 | class WasmEdgeTensorflowFakeRunSession 35 | : public WasmEdgeTensorflowFake { 36 | public: 37 | Expect body(const Runtime::CallingFrame &, uint64_t Cxt) { 38 | return 0; 39 | } 40 | }; 41 | 42 | class WasmEdgeTensorflowFakeGetOutputTensor 43 | : public WasmEdgeTensorflowFake { 44 | public: 45 | Expect body(const Runtime::CallingFrame &, uint64_t Cxt, 46 | uint32_t OutputPtr, uint32_t OutputLen, uint32_t Idx) { 47 | return 0; 48 | } 49 | }; 50 | 51 | class WasmEdgeTensorflowFakeGetTensorLen 52 | : public WasmEdgeTensorflowFake { 53 | public: 54 | Expect body(const Runtime::CallingFrame &, uint64_t Tensor) { 55 | return 0; 56 | } 57 | }; 58 | 59 | class WasmEdgeTensorflowFakeGetTensorData 60 | : public WasmEdgeTensorflowFake { 61 | public: 62 | Expect body(const Runtime::CallingFrame &, uint64_t Tensor, 63 | uint32_t BufPtr) { 64 | return {}; 65 | } 66 | }; 67 | 68 | class WasmEdgeTensorflowFakeAppendInput 69 | : public WasmEdgeTensorflowFake { 70 | public: 71 | Expect body(const Runtime::CallingFrame &, uint64_t Cxt, 72 | uint32_t InputPtr, uint32_t InputLen, uint32_t Idx, 73 | uint32_t DimPtr, uint32_t DimCnt, uint32_t DataType, 74 | uint32_t TensorBufPtr, uint32_t TensorBufLen) { 75 | return {}; 76 | } 77 | }; 78 | 79 | class WasmEdgeTensorflowFakeAppendOutput 80 | : public WasmEdgeTensorflowFake { 81 | public: 82 | Expect body(const Runtime::CallingFrame &, uint64_t Cxt, 83 | uint32_t OutputPtr, uint32_t OutputLen, uint32_t Idx) { 84 | return {}; 85 | } 86 | }; 87 | 88 | class WasmEdgeTensorflowFakeClearInput 89 | : public WasmEdgeTensorflowFake { 90 | public: 91 | Expect body(const Runtime::CallingFrame &, uint64_t Cxt) { return {}; } 92 | }; 93 | 94 | class WasmEdgeTensorflowFakeClearOutput 95 | : public WasmEdgeTensorflowFake { 96 | public: 97 | Expect body(const Runtime::CallingFrame &, uint64_t Cxt) { return {}; } 98 | }; 99 | 100 | } // namespace Host 101 | } // namespace WasmEdge 102 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | concurrency: 4 | group: build-${{ github.head_ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | push: 9 | branches: 10 | - master 11 | paths-ignore: 12 | - 'docs/**' 13 | - '*.md' 14 | pull_request: 15 | branches: 16 | - master 17 | paths-ignore: 18 | - 'docs/**' 19 | - '*.md' 20 | 21 | jobs: 22 | build_manylinux: 23 | strategy: 24 | matrix: 25 | include: 26 | - name: manylinux2014 x86_64 27 | host_runner: ubuntu-latest 28 | docker_tag: manylinux2014_x86_64 29 | - name: manylinux2014 aarch64 30 | host_runner: linux-arm64 31 | docker_tag: manylinux2014_aarch64 32 | name: ${{ matrix.name }} platform 33 | runs-on: ${{ matrix.host_runner }} 34 | container: 35 | image: wasmedge/wasmedge:${{ matrix.docker_tag }} 36 | steps: 37 | - name: Checkout code 38 | uses: actions/checkout@v3 39 | with: 40 | submodules: true 41 | - name: Build ${{ matrix.name }} package 42 | run: | 43 | export PATH="/toolchain/bin:$PATH" 44 | export CC=gcc 45 | export CXX=g++ 46 | export CPPFLAGS=-I/toolchain/include 47 | export LDFLAGS=-L/toolchain/lib64 48 | curl -s -L -O --remote-name-all https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2 49 | echo "475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39 boost_1_79_0.tar.bz2" | sha256sum -c 50 | bzip2 -dc boost_1_79_0.tar.bz2 | tar -xf - 51 | if ! cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release -DBoost_NO_SYSTEM_PATHS=TRUE -DBOOST_INCLUDEDIR=$(pwd)/boost_1_79_0/; then 52 | echo === CMakeOutput.log === 53 | cat build/CMakeFiles/CMakeOutput.log 54 | echo === CMakeError.log === 55 | cat build/CMakeFiles/CMakeError.log 56 | exit 1 57 | fi 58 | cmake --build build 59 | 60 | build_and_ubuntu: 61 | name: Ubuntu 20.04 x86_64 platform 62 | runs-on: ubuntu-latest 63 | container: 64 | image: wasmedge/wasmedge:ubuntu-build-clang 65 | steps: 66 | - name: Checkout code 67 | uses: actions/checkout@v3 68 | with: 69 | submodules: true 70 | - name: Build WasmEdge-tensorflow for Ubuntu 20.04 x86_64 71 | run: | 72 | git config --global --add safe.directory $(pwd) 73 | if ! cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release; then 74 | echo === CMakeOutput.log === 75 | cat build/CMakeFiles/CMakeOutput.log 76 | echo === CMakeError.log === 77 | cat build/CMakeFiles/CMakeError.log 78 | exit 1 79 | fi 80 | cmake --build build 81 | 82 | build_darwin_x86_64: 83 | name: Darwin x86_64 platform 84 | runs-on: macos-11 85 | steps: 86 | - name: Checkout code 87 | uses: actions/checkout@v3 88 | with: 89 | submodules: true 90 | - name: Build WasmEdge-tensorflow for Darwin x86_64 91 | run: | 92 | brew install llvm ninja boost cmake 93 | export LLVM_DIR="/usr/local/opt/llvm/lib/cmake" 94 | export CC=clang 95 | export CXX=clang++ 96 | if ! cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release; then 97 | echo === CMakeOutput.log === 98 | cat build/CMakeFiles/CMakeOutput.log 99 | echo === CMakeError.log === 100 | cat build/CMakeFiles/CMakeError.log 101 | exit 1 102 | fi 103 | cmake --build build 104 | 105 | build_android: 106 | name: Android platforms 107 | runs-on: ubuntu-latest 108 | container: 109 | image: wasmedge/wasmedge:latest 110 | steps: 111 | - name: Checkout code 112 | uses: actions/checkout@v3 113 | with: 114 | submodules: true 115 | - name: Install dependency 116 | run: | 117 | apt update && apt install -y unzip 118 | apt remove -y cmake 119 | curl -sLO https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz 120 | tar -zxf cmake-3.22.2-linux-x86_64.tar.gz 121 | cp -r cmake-3.22.2-linux-x86_64/bin /usr/local 122 | cp -r cmake-3.22.2-linux-x86_64/share /usr/local 123 | curl -sLO https://dl.google.com/android/repository/android-ndk-r23b-linux.zip 124 | unzip -q android-ndk-r23b-linux.zip 125 | - name: Build WasmEdge-tensorflow for Android 126 | run: | 127 | export ANDROID_NDK_HOME=$(pwd)/android-ndk-r23b/ 128 | if ! cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release -DWASMEDGE_BUILD_AOT_RUNTIME=OFF -DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=23 -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a -DCMAKE_ANDROID_NDK=$ANDROID_NDK_HOME -DCMAKE_ANDROID_STL_TYPE=c++_static; then 129 | echo === CMakeOutput.log === 130 | cat build/CMakeFiles/CMakeOutput.log 131 | echo === CMakeError.log === 132 | cat build/CMakeFiles/CMakeError.log 133 | exit 1 134 | fi 135 | cmake --build build 136 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WasmEdge for Tensorflow Extension (WILL BE DEPRECATED SOON) 2 | 3 | > The WasmEdge extension will be deprecated soon and be replaced by the [WasmEdge-Tensorflow plug-in](https://wasmedge.org/docs/contribute/source/plugin/tensorflow) and the [WasmEdge-TensorflowLite plug-in](https://wasmedge.org/docs/contribute/source/plugin/tensorflowlite). 4 | 5 | The [WasmEdge](https://github.com/WasmEdge/WasmEdge) is a high performance WebAssembly runtime optimized for server side applications. This project provides support for accessing with [Tensorflow C library](https://www.tensorflow.org/install/lang_c). 6 | 7 | ## Getting Started 8 | 9 | ### Requirements 10 | 11 | The WasmEdge Tensorflow shared library `libwasmedge-tensorflow_c.so` and `libwasmedge-tensorflowlite_c.so` are provided for the `WasmEdge-Tensorflow` extension of the WasmEdge shared library. 12 | The WasmEdge Tensorflow static library `libwasmedgeHostModuleWasmEdgeTensorflow.a` and `libwasmedgeHostModuleWasmEdgeTensorflowLite.a` are provided for statical linking when building executables with CMake. 13 | When linking with `libwasmedge-tensorflow_c.so` and `libwasmedgeHostModuleWasmEdgeTensorflow.a`, the TensorFlow shared libraries `libtensorflow_cc.so` and `libtensorflow_framework.so` are required. 14 | When linking with `libwasmedge-tensorflowlite_c.so` and `libwasmedgeHostModuleWasmEdgeTensorflowLite.a`, the TensorFlow-Lite shared library `libtensorflowlite_c.so` is required. 15 | 16 | The official TensorFlow release only provide the TensorFlow shared library. 17 | You can download and install the pre-built shared libraries: 18 | 19 | ```bash 20 | wget https://github.com/second-state/WasmEdge-tensorflow-deps/releases/download/0.12.1/WasmEdge-tensorflow-deps-TF-0.12.1-manylinux2014_x86_64.tar.gz 21 | tar -zxvf WasmEdge-tensorflow-deps-TF-0.12.1-manylinux2014_x86_64.tar.gz 22 | rm -f WasmEdge-tensorflow-deps-TF-0.12.1-manylinux2014_x86_64.tar.gz 23 | ln -sf libtensorflow_cc.so.2.6.0 libtensorflow_cc.so.2 24 | ln -sf libtensorflow_cc.so.2 libtensorflow_cc.so 25 | ln -sf libtensorflow_framework.so.2.6.0 libtensorflow_framework.so.2 26 | ln -sf libtensorflow_framework.so.2 libtensorflow_framework.so 27 | wget https://github.com/second-state/WasmEdge-tensorflow-deps/releases/download/0.12.1/WasmEdge-tensorflow-deps-TFLite-0.12.1-manylinux2014_x86_64.tar.gz 28 | tar -zxvf WasmEdge-tensorflow-deps-TFLite-0.12.1-manylinux2014_x86_64.tar.gz 29 | rm -f WasmEdge-tensorflow-deps-TFLite-0.12.1-manylinux2014_x86_64.tar.gz 30 | ``` 31 | 32 | ### Prepare the environment 33 | 34 | #### Use our docker image (Recommanded) 35 | 36 | Our docker image is based on `ubuntu 20.04`. 37 | 38 | ```bash 39 | docker pull wasmedge/wasmedge 40 | ``` 41 | 42 | #### Or setup the environment manually 43 | 44 | Please notice that WasmEdge-Tensorflow requires cmake>=3.11 and libboost>=1.68. 45 | 46 | ```bash 47 | # Tools and libraries 48 | sudo apt install -y \ 49 | software-properties-common \ 50 | cmake \ 51 | libboost-all-dev 52 | 53 | # WasmEdge supports both clang++ and g++ compilers 54 | # You can choose one of them for building this project 55 | sudo apt install -y gcc g++ 56 | sudo apt install -y clang 57 | ``` 58 | 59 | ### Get WasmEdge-Tensorflow Source Code 60 | 61 | ```bash 62 | git clone --recursive https://github.com/second-state/WasmEdge-tensorflow.git 63 | cd WasmEdge-tensorflow 64 | git checkout 0.12.1 65 | ``` 66 | 67 | ### Build WasmEdge-Tensorflow 68 | 69 | WasmEdge-Tensorflow depends on WasmEdge-Core, you have to prepare WasmEdge-Core before you build WasmEdge-Tensorflow. 70 | We provides two options for setting up the WasmEdge-Core: 71 | 72 | #### Create and Enter the Build Folder 73 | 74 | ```bash 75 | # After pulling our WasmEdge docker image 76 | docker run -it --rm \ 77 | -v :/root/WasmEdge-tensorflow \ 78 | wasmedge/wasmedge:latest 79 | # In docker 80 | cd /root/WasmEdge-tensorflow 81 | mkdir -p build && cd build 82 | ``` 83 | 84 | #### Option 1. Use built-in CMakeLists to get WasmEdge-Core (Recommended) 85 | 86 | ```bash 87 | # In docker 88 | cmake -DCMAKE_BUILD_TYPE=Release .. && make 89 | ``` 90 | 91 | #### Option 2. Use specific version of WasmEdge-Core by giving WASMEDGE_CORE_PATH 92 | 93 | ```bash 94 | # In docker 95 | cmake -DWASMEDGE_CORE_PATH= -DCMAKE_BUILD_TYPE=Release .. && make 96 | ``` 97 | 98 | The shared library `build/lib/libwasmedge-tensorflow_c.so` is the C API to create the `wasmedge-tensorflow` import object. 99 | The header `build/include/wasmedge-tensorflow.h` is the header of the `libwasmedge-tensorflow_c.so` shared library. 100 | The shared library `build/lib/libwasmedge-tensorflowlite_c.so` is the C API to create the `wasmedge-tensorflowlite` import object. 101 | The header `build/include/wasmedge-tensorflowlite.h` is the header of the `libwasmedge-tensorflowlite_c.so` shared library. 102 | The static library `build/lib/libwasmedgeHostModuleWasmEdgeTensorflow.a` is for executables linking in CMake. 103 | The static library `build/lib/libwasmedgeHostModuleWasmEdgeTensorflowLite.a` is for executables linking in CMake. 104 | 105 | ## WasmEdge-Tensorflow Tools 106 | 107 | The tools is moved to the new [repository](https://github.com/second-state/WasmEdge-tensorflow-tools). 108 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | cmake_minimum_required(VERSION 3.11) 5 | cmake_policy(SET CMP0091 NEW) 6 | project(WasmEdge-Tensorflow) 7 | 8 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 9 | if(NOT CMAKE_BUILD_TYPE) 10 | set(CMAKE_BUILD_TYPE RelWithDebInfo) 11 | endif() 12 | 13 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF) 14 | if(CMAKE_BUILD_TYPE STREQUAL Release OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) 15 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) 16 | if (CMAKE_GENERATOR STREQUAL Ninja) 17 | if(CMAKE_COMPILER_IS_GNUCXX) 18 | list(TRANSFORM CMAKE_C_COMPILE_OPTIONS_IPO REPLACE "^-flto$" "-flto=auto") 19 | list(TRANSFORM CMAKE_CXX_COMPILE_OPTIONS_IPO REPLACE "^-flto$" "-flto=auto") 20 | endif() 21 | set(CMAKE_JOB_POOLS "link=2") 22 | set(CMAKE_JOB_POOL_LINK link) 23 | endif() 24 | endif() 25 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") 26 | set(CMAKE_CXX_STANDARD 17) 27 | set(CMAKE_CXX_EXTENSIONS OFF) 28 | set(CMAKE_CXX_VISIBILITY_PRESET hidden) 29 | set(CMAKE_ENABLE_EXPORTS ON) 30 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 31 | set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) 32 | set(CMAKE_SKIP_RPATH ON) 33 | 34 | # List of WasmEdge options 35 | option(WASMEDGE_BUILD_TOOLS "Generate wasmedge and wasmedgec tools." OFF) 36 | # Libraries will be built in this project, hence the wasmedge and wasmedgec are not needed. 37 | option(WASMEDGE_BUILD_AOT_RUNTIME "Enable WasmEdge LLVM-based ahead of time compilation runtime." OFF) 38 | # AOT runtime is not needed in this stand-alone project. 39 | option(WASMEDGE_BUILD_SHARED_LIB "Generate the WasmEdge shared library." OFF) 40 | # libwasmedge_c.so is not needed in this stand-alone project. 41 | option(WASMEDGE_TENSORFLOW_BUILD_SHARED_LIB "Generate the libwasmedge-tensorflow_c and libwasmedge-tensorflowlite_c shared libraries." ON) 42 | 43 | # WasmEdge repositories versions 44 | if(NOT WASMEDGE_REPO_VERSION) 45 | set(WASMEDGE_REPO_VERSION "0.13.0-alpha.1") 46 | endif() 47 | # WasmEdge dependencies versions 48 | if(NOT WASMEDGE_DEPS_VERSION) 49 | set(WASMEDGE_DEPS_VERSION "TF-2.12.0-CC") 50 | endif() 51 | 52 | # Check the build architecture and system. 53 | if(ANDROID) 54 | if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") 55 | if(NOT WASMEDGE_TENSORFLOW_SYSTEM_NAME) 56 | set(WASMEDGE_TENSORFLOW_SYSTEM_NAME "android_aarch64") 57 | endif() 58 | else() 59 | message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}") 60 | endif() 61 | elseif(APPLE) 62 | if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64") 63 | if(NOT WASMEDGE_TENSORFLOW_SYSTEM_NAME) 64 | set(WASMEDGE_TENSORFLOW_SYSTEM_NAME "darwin_x86_64") 65 | endif() 66 | elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") 67 | if(NOT WASMEDGE_TENSORFLOW_SYSTEM_NAME) 68 | set(WASMEDGE_TENSORFLOW_SYSTEM_NAME "darwin_arm64") 69 | endif() 70 | else() 71 | message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}") 72 | endif() 73 | elseif(UNIX) 74 | if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64") 75 | if(NOT WASMEDGE_TENSORFLOW_SYSTEM_NAME) 76 | set(WASMEDGE_TENSORFLOW_SYSTEM_NAME "manylinux2014_x86_64") 77 | endif() 78 | elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") 79 | if(NOT WASMEDGE_TENSORFLOW_SYSTEM_NAME) 80 | set(WASMEDGE_TENSORFLOW_SYSTEM_NAME "manylinux2014_aarch64") 81 | endif() 82 | else() 83 | message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}") 84 | endif() 85 | else() 86 | message(FATAL_ERROR "Unsupported system: ${CMAKE_SYSTEM_NAME}") 87 | endif() 88 | 89 | # Clone WasmEdge-core 90 | if(NOT WASMEDGE_CORE_PATH) 91 | include(FetchContent) 92 | FetchContent_Declare( 93 | wasmedge 94 | GIT_REPOSITORY https://github.com/WasmEdge/WasmEdge.git 95 | GIT_TAG ${WASMEDGE_REPO_VERSION} 96 | ) 97 | 98 | FetchContent_GetProperties(wasmedge) 99 | if(NOT wasmedge_POPULATED) 100 | message(STATUS "Fetching WasmEdge repository") 101 | FetchContent_Populate(wasmedge) 102 | message(STATUS "Fetching WasmEdge repository - done") 103 | endif() 104 | add_subdirectory(${wasmedge_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/utils/WasmEdge-core) 105 | set(WASMEDGE_CORE_PATH ${wasmedge_SOURCE_DIR}) 106 | set(WASMEDGE_CORE_BIN_PATH ${CMAKE_CURRENT_BINARY_DIR}/utils/WasmEdge-core) 107 | else() 108 | get_filename_component( 109 | WASMEDGE_CORE_PATH "${WASMEDGE_CORE_PATH}" 110 | REALPATH 111 | BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") 112 | if(NOT WASMEDGE_CORE_BIN_PATH) 113 | add_subdirectory(${WASMEDGE_CORE_PATH} ${CMAKE_CURRENT_BINARY_DIR}/utils/WasmEdge-core) 114 | set(WASMEDGE_CORE_BIN_PATH ${CMAKE_CURRENT_BINARY_DIR}/utils/WasmEdge-core) 115 | else() 116 | get_filename_component( 117 | WASMEDGE_CORE_BIN_PATH "${WASMEDGE_CORE_BIN_PATH}" 118 | REALPATH 119 | BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") 120 | endif() 121 | endif() 122 | 123 | message(STATUS "WasmEdge-tensorflow: Set WasmEdge-core source path: ${WASMEDGE_CORE_PATH}") 124 | message(STATUS "WasmEdge-tensorflow: Set WasmEdge-core binary path: ${WASMEDGE_CORE_BIN_PATH}") 125 | 126 | # TensorFlow dependencies library 127 | add_subdirectory(utils/WasmEdge-tensorflow-deps) 128 | 129 | include_directories(BEFORE 130 | ${CMAKE_CURRENT_BINARY_DIR}/include 131 | ${CMAKE_CURRENT_SOURCE_DIR}/include 132 | ) 133 | 134 | add_subdirectory(include) 135 | add_subdirectory(lib) 136 | -------------------------------------------------------------------------------- /lib/tensorflowlite_func.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #include 5 | #include 6 | 7 | #include "tensorflow/lite/c/c_api.h" 8 | 9 | #include "common/log.h" 10 | #include "common/span.h" 11 | #include "tensorflowlite_func.h" 12 | 13 | namespace WasmEdge { 14 | namespace Host { 15 | 16 | Expect 17 | WasmEdgeTensorflowLiteCreateSession::body(const Runtime::CallingFrame &Frame, 18 | uint32_t ModBufPtr, 19 | uint32_t ModBufLen) { 20 | // Check memory instance from module. 21 | auto *MemInst = Frame.getMemoryByIndex(0); 22 | if (MemInst == nullptr) { 23 | return Unexpect(ErrCode::Value::HostFuncError); 24 | } 25 | 26 | // Create context and import graph. 27 | struct WasmEdgeTensorflowLiteContext *Cxt = 28 | new WasmEdgeTensorflowLiteContext(); 29 | auto *Model = 30 | TfLiteModelCreate(MemInst->getPointer(ModBufPtr), ModBufLen); 31 | if (Model == nullptr) { 32 | spdlog::error("wasmedge_tensorflowlite_create_session: Cannot import " 33 | "TFLite model."); 34 | return 0; 35 | } 36 | auto *Ops = TfLiteInterpreterOptionsCreate(); 37 | TfLiteInterpreterOptionsSetNumThreads(Ops, 2); 38 | Cxt->Interp = TfLiteInterpreterCreate(Model, Ops); 39 | TfLiteInterpreterOptionsDelete(Ops); 40 | TfLiteModelDelete(Model); 41 | if (Cxt->Interp == nullptr) { 42 | spdlog::error("wasmedge_tensorflowlite_create_session: Cannot create " 43 | "TFLite interpreter."); 44 | return 0; 45 | } 46 | TfLiteInterpreterAllocateTensors(Cxt->Interp); 47 | return static_cast(reinterpret_cast(Cxt)); 48 | } 49 | 50 | Expect 51 | WasmEdgeTensorflowLiteDeleteSession::body(const Runtime::CallingFrame &, 52 | uint64_t Cxt) { 53 | // Context struct 54 | auto *C = reinterpret_cast(Cxt); 55 | if (C != nullptr) { 56 | delete C; 57 | } 58 | return {}; 59 | } 60 | 61 | Expect 62 | WasmEdgeTensorflowLiteRunSession::body(const Runtime::CallingFrame &, 63 | uint64_t Cxt) { 64 | // Context struct 65 | auto *C = reinterpret_cast(Cxt); 66 | 67 | // Run session 68 | TfLiteStatus Stat = TfLiteInterpreterInvoke(C->Interp); 69 | if (Stat != TfLiteStatus::kTfLiteOk) { 70 | spdlog::error("wasmedge_tensorflowlite_run_session: Invokation failed."); 71 | return 1; 72 | } 73 | return 0; 74 | } 75 | 76 | Expect 77 | WasmEdgeTensorflowLiteGetOutputTensor::body(const Runtime::CallingFrame &Frame, 78 | uint64_t Cxt, uint32_t OutputPtr, 79 | uint32_t OutputLen) { 80 | // Check memory instance from module. 81 | auto *MemInst = Frame.getMemoryByIndex(0); 82 | if (MemInst == nullptr) { 83 | return Unexpect(ErrCode::Value::HostFuncError); 84 | } 85 | 86 | // Context struct 87 | auto *C = reinterpret_cast(Cxt); 88 | 89 | // Find the output tensor 90 | std::string Name(MemInst->getPointer(OutputPtr), OutputLen); 91 | uint32_t OutCnt = TfLiteInterpreterGetOutputTensorCount(C->Interp); 92 | 93 | for (uint32_t I = 0; I < OutCnt; ++I) { 94 | const TfLiteTensor *T = TfLiteInterpreterGetOutputTensor(C->Interp, I); 95 | if (Name == std::string(TfLiteTensorName(T))) { 96 | return static_cast(reinterpret_cast(T)); 97 | } 98 | } 99 | return 0; 100 | } 101 | 102 | Expect 103 | WasmEdgeTensorflowLiteGetTensorLen::body(const Runtime::CallingFrame &, 104 | uint64_t Tensor) { 105 | // Return tensor data length. 106 | TfLiteTensor *T = reinterpret_cast(Tensor); 107 | if (T != nullptr) { 108 | return TfLiteTensorByteSize(T); 109 | } 110 | return 0; 111 | } 112 | 113 | Expect 114 | WasmEdgeTensorflowLiteGetTensorData::body(const Runtime::CallingFrame &Frame, 115 | uint64_t Tensor, uint32_t BufPtr) { 116 | // Check memory instance from module. 117 | auto *MemInst = Frame.getMemoryByIndex(0); 118 | if (MemInst == nullptr) { 119 | return Unexpect(ErrCode::Value::HostFuncError); 120 | } 121 | 122 | // Copy tensor data to buffer. 123 | TfLiteTensor *T = reinterpret_cast(Tensor); 124 | if (T != nullptr) { 125 | uint8_t *Buf = MemInst->getPointer(BufPtr); 126 | if (TfLiteTensorByteSize(T) > 0) { 127 | TfLiteTensorCopyToBuffer(T, Buf, TfLiteTensorByteSize(T)); 128 | } 129 | } 130 | return {}; 131 | } 132 | 133 | Expect WasmEdgeTensorflowLiteAppendInput::body( 134 | const Runtime::CallingFrame &Frame, uint64_t Cxt, uint32_t InputPtr, 135 | uint32_t InputLen, uint32_t TensorBufPtr, uint32_t TensorBufLen) { 136 | // Check memory instance from module. 137 | auto *MemInst = Frame.getMemoryByIndex(0); 138 | if (MemInst == nullptr) { 139 | return Unexpect(ErrCode::Value::HostFuncError); 140 | } 141 | 142 | // Context struct 143 | auto *C = reinterpret_cast(Cxt); 144 | 145 | // Find the input tensor 146 | std::string Name(MemInst->getPointer(InputPtr), InputLen); 147 | uint32_t InCnt = TfLiteInterpreterGetInputTensorCount(C->Interp); 148 | 149 | for (uint32_t I = 0; I < InCnt; ++I) { 150 | auto *T = TfLiteInterpreterGetInputTensor(C->Interp, I); 151 | if (Name == std::string(TfLiteTensorName(T))) { 152 | TfLiteTensorCopyFromBuffer( 153 | T, MemInst->getPointer(TensorBufPtr), TensorBufLen); 154 | break; 155 | } 156 | } 157 | return {}; 158 | } 159 | 160 | } // namespace Host 161 | } // namespace WasmEdge 162 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | # SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | # Determine the TensorFlow is need to build. 5 | if(APPLE OR (UNIX AND NOT ANDROID)) 6 | set(WASMEDGE_TENSORFLOW_BUILD_TF ON) 7 | endif() 8 | 9 | if(WASMEDGE_TENSORFLOW_BUILD_TF) 10 | # Build WasmEdge-Tensoflow. 11 | add_library(wasmedgeHostModuleWasmEdgeTensorflow 12 | tensorflow_module.cpp 13 | tensorflow_func.cpp 14 | ) 15 | 16 | target_link_libraries(wasmedgeHostModuleWasmEdgeTensorflow 17 | PUBLIC 18 | wasmedgeCommon 19 | wasmedgeSystem 20 | ) 21 | 22 | target_include_directories(wasmedgeHostModuleWasmEdgeTensorflow 23 | PUBLIC 24 | ${TENSORFLOW_INCLUDE} 25 | ${WASMEDGE_CORE_PATH}/include 26 | ) 27 | endif() 28 | 29 | # Build WasmEdge-Tensoflow-Lite. 30 | add_library(wasmedgeHostModuleWasmEdgeTensorflowLite 31 | tensorflowlite_module.cpp 32 | tensorflowlite_func.cpp 33 | ) 34 | 35 | target_include_directories(wasmedgeHostModuleWasmEdgeTensorflowLite 36 | PUBLIC 37 | ${TENSORFLOW_INCLUDE} 38 | ${WASMEDGE_CORE_PATH}/include 39 | ) 40 | 41 | target_link_libraries(wasmedgeHostModuleWasmEdgeTensorflowLite 42 | PUBLIC 43 | wasmedgeCommon 44 | wasmedgeSystem 45 | ) 46 | 47 | # Linking libwasmedge-tensorflowlite_c.so for Android needs the libtensorflowlite_c.so. 48 | if(ANDROID) 49 | if(NOT WASMEDGE_TENSORFLOW_DEPS_TFLITE_LIB) 50 | FetchContent_Declare( 51 | wasmedgetensorflowdepslite 52 | URL "https://github.com/second-state/WasmEdge-tensorflow-deps/releases/download/${WASMEDGE_DEPS_VERSION}/WasmEdge-tensorflow-deps-TFLite-${WASMEDGE_DEPS_VERSION}-android_aarch64.tar.gz" 53 | URL_HASH "SHA256=2d7dcd7381479d9ffc0968ea66e24a5207b404c7f2ccbdddec6f2a4d6f9813f2" 54 | ) 55 | FetchContent_GetProperties(wasmedgetensorflowdepslite) 56 | if (NOT wasmedgetensorflowdepslite_POPULATED) 57 | FetchContent_Populate(wasmedgetensorflowdepslite) 58 | endif() 59 | set(WASMEDGE_TENSORFLOW_DEPS_TFLITE_LIB 60 | "${wasmedgetensorflowdepslite_SOURCE_DIR}/libtensorflowlite_c.so" 61 | ) 62 | endif() 63 | endif() 64 | 65 | # Linking libwasmedge-tensorflow_c.dylib for MacOS needs the libtensorflow_cc.2.6.0.dylib and libtensorflow_framework.2.6.0.dylib. 66 | # Linking libwasmedge-tensorflowlite_c.dylib for MacOS needs the libtensorflowlite_c.dylib and libtensorflowlite_flex.dylib. 67 | if(APPLE) 68 | if(NOT WASMEDGE_TENSORFLOW_DEPS_TFLITE_LIB) 69 | if(WASMEDGE_TENSORFLOW_SYSTEM_NAME STREQUAL "darwin_x86_64") 70 | set(WASMEDGE_TENSORFLOW_DEPS_TFLITE_HASH "04b58f4b97220633a8e299a63aba73d9a1f228904081e7d5f18e78d1e38d5f00") 71 | elseif(WASMEDGE_TENSORFLOW_SYSTEM_NAME STREQUAL "darwin_arm64") 72 | set(WASMEDGE_TENSORFLOW_DEPS_TFLITE_HASH "cb4562a80ac2067bdabe2464b80e129b9d8ddc6d97ad1a2d7215e06a1e1e8cda") 73 | endif() 74 | 75 | FetchContent_Declare( 76 | wasmedgetensorflowdepslite 77 | URL "https://github.com/second-state/WasmEdge-tensorflow-deps/releases/download/${WASMEDGE_DEPS_VERSION}/WasmEdge-tensorflow-deps-TFLite-${WASMEDGE_DEPS_VERSION}-${WASMEDGE_TENSORFLOW_SYSTEM_NAME}.tar.gz" 78 | URL_HASH "SHA256=${WASMEDGE_TENSORFLOW_DEPS_TFLITE_HASH}" 79 | ) 80 | FetchContent_GetProperties(wasmedgetensorflowdepslite) 81 | if (NOT wasmedgetensorflowdepslite_POPULATED) 82 | FetchContent_Populate(wasmedgetensorflowdepslite) 83 | endif() 84 | set(WASMEDGE_TENSORFLOW_DEPS_TFLITE_LIB 85 | "${wasmedgetensorflowdepslite_SOURCE_DIR}/libtensorflowlite_c.dylib" 86 | "${wasmedgetensorflowdepslite_SOURCE_DIR}/libtensorflowlite_flex.dylib" 87 | ) 88 | endif() 89 | 90 | if(WASMEDGE_TENSORFLOW_BUILD_TF AND NOT WASMEDGE_TENSORFLOW_DEPS_TF_LIB) 91 | if(WASMEDGE_TENSORFLOW_SYSTEM_NAME STREQUAL "darwin_x86_64") 92 | set(WASMEDGE_TENSORFLOW_DEPS_TF_HASH "60da72a093cf65d733ca2cb9f331356a1637acfe1645050809bd0cf056b1520f") 93 | elseif(WASMEDGE_TENSORFLOW_SYSTEM_NAME STREQUAL "darwin_arm64") 94 | set(WASMEDGE_TENSORFLOW_DEPS_TF_HASH "2ede6d96c7563eb826331469d7d0a1f51c9b1ca311f4398d841f679a5b96705a") 95 | endif() 96 | 97 | FetchContent_Declare( 98 | wasmedgetensorflowdeps 99 | URL "https://github.com/second-state/WasmEdge-tensorflow-deps/releases/download/${WASMEDGE_DEPS_VERSION}/WasmEdge-tensorflow-deps-TF-${WASMEDGE_DEPS_VERSION}-${WASMEDGE_TENSORFLOW_SYSTEM_NAME}.tar.gz" 100 | URL_HASH "SHA256=${WASMEDGE_TENSORFLOW_DEPS_TF_HASH}" 101 | ) 102 | FetchContent_GetProperties(wasmedgetensorflowdeps) 103 | if(NOT wasmedgetensorflowdeps_POPULATED) 104 | FetchContent_Populate(wasmedgetensorflowdeps) 105 | execute_process( 106 | COMMAND ${CMAKE_COMMAND} -E create_symlink libtensorflow_cc.2.12.0.dylib ${wasmedgetensorflowdeps_SOURCE_DIR}/libtensorflow_cc.2.dylib 107 | COMMAND ${CMAKE_COMMAND} -E create_symlink libtensorflow_cc.2.dylib ${wasmedgetensorflowdeps_SOURCE_DIR}/libtensorflow_cc.dylib 108 | COMMAND ${CMAKE_COMMAND} -E create_symlink libtensorflow_framework.2.12.0.dylib ${wasmedgetensorflowdeps_SOURCE_DIR}/libtensorflow_framework.2.dylib 109 | COMMAND ${CMAKE_COMMAND} -E create_symlink libtensorflow_framework.2.dylib ${wasmedgetensorflowdeps_SOURCE_DIR}/libtensorflow_framework.dylib 110 | ) 111 | endif() 112 | set(WASMEDGE_TENSORFLOW_DEPS_TF_LIB 113 | "${wasmedgetensorflowdeps_SOURCE_DIR}/libtensorflow_cc.2.12.0.dylib" 114 | "${wasmedgetensorflowdeps_SOURCE_DIR}/libtensorflow_framework.2.12.0.dylib" 115 | ) 116 | endif() 117 | endif() 118 | 119 | # Build WasmEdge-TensorFlow and WasmEdge-TensorFlow-Lite C-API. 120 | if(WASMEDGE_TENSORFLOW_BUILD_SHARED_LIB) 121 | if(WASMEDGE_TENSORFLOW_BUILD_TF) 122 | # Build WasmEdge-TensorFlow C-API. 123 | add_library(wasmedge-tensorflow_c SHARED 124 | wasmedge-tensorflow.cpp 125 | tensorflow_module.cpp 126 | tensorflow_func.cpp 127 | ) 128 | 129 | target_include_directories(wasmedge-tensorflow_c 130 | PUBLIC 131 | ${TENSORFLOW_INCLUDE} 132 | ${WASMEDGE_CORE_PATH}/include 133 | ${WASMEDGE_CORE_BIN_PATH}/include/api 134 | ) 135 | 136 | target_link_libraries(wasmedge-tensorflow_c 137 | PRIVATE 138 | wasmedgeCommon 139 | wasmedgeSystem 140 | ) 141 | 142 | if(APPLE) 143 | target_link_libraries(wasmedge-tensorflow_c 144 | PRIVATE 145 | ${WASMEDGE_TENSORFLOW_DEPS_TF_LIB} 146 | ) 147 | endif() 148 | endif() 149 | 150 | # Build WasmEdge-TensorFlow-Lite C-API. 151 | add_library(wasmedge-tensorflowlite_c SHARED 152 | wasmedge-tensorflowlite.cpp 153 | tensorflowlite_module.cpp 154 | tensorflowlite_func.cpp 155 | ) 156 | 157 | target_include_directories(wasmedge-tensorflowlite_c 158 | PUBLIC 159 | ${TENSORFLOW_INCLUDE} 160 | ${WASMEDGE_CORE_PATH}/include 161 | ${WASMEDGE_CORE_BIN_PATH}/include/api 162 | ) 163 | 164 | target_link_libraries(wasmedge-tensorflowlite_c 165 | PRIVATE 166 | wasmedgeCommon 167 | wasmedgeSystem 168 | ) 169 | 170 | if(ANDROID OR APPLE) 171 | target_link_libraries(wasmedge-tensorflowlite_c 172 | PRIVATE 173 | ${WASMEDGE_TENSORFLOW_DEPS_TFLITE_LIB} 174 | ) 175 | endif() 176 | endif() 177 | -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | ### 0.12.1 (2023-05-12) 2 | 3 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 4 | Please refer to the [WasmEdge 0.12.1](https://github.com/WasmEdge/WasmEdge/releases/tag/0.12.1) for more details. 5 | 6 | Features: 7 | 8 | * Update the `WasmEdge` dependency to `0.12.1`. 9 | 10 | ### 0.12.0 (2023-04-25) 11 | 12 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 13 | Please refer to the [WasmEdge 0.12.0](https://github.com/WasmEdge/WasmEdge/releases/tag/0.12.0) for more details. 14 | 15 | Features: 16 | 17 | * Update the `WasmEdge` dependency to `0.12.0`. 18 | * Update to use the `libtensorflow_cc` C++ API. 19 | * Added the Ubuntu 20.04 version. 20 | 21 | ### 0.11.2 (2022-11-01) 22 | 23 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 24 | Please refer to the [WasmEdge 0.11.2](https://github.com/WasmEdge/WasmEdge/releases/tag/0.11.2) for more details. 25 | 26 | Features: 27 | 28 | * Update the `WasmEdge` dependency to `0.11.2`. 29 | 30 | ### 0.11.1 (2022-10-03) 31 | 32 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 33 | Please refer to the [WasmEdge 0.11.1](https://github.com/WasmEdge/WasmEdge/releases/tag/0.11.1) for more details. 34 | 35 | Features: 36 | 37 | * Update the `WasmEdge` dependency to `0.11.1`. 38 | 39 | ### 0.11.0 (2022-08-31) 40 | 41 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 42 | Please refer to the [WasmEdge 0.11.0](https://github.com/WasmEdge/WasmEdge/releases/tag/0.11.0) for more details. 43 | 44 | Features: 45 | 46 | * Update the `WasmEdge` dependency to `0.11.0`. 47 | * Update the host functions for the breaking changes. 48 | 49 | ### 0.10.1 (2022-07-28) 50 | 51 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 52 | Please refer to the [WasmEdge 0.10.1](https://github.com/WasmEdge/WasmEdge/releases/tag/0.10.1) for more details. 53 | 54 | Features: 55 | 56 | * Update the `WasmEdge` dependency to `0.10.1`. 57 | 58 | ### 0.10.0 (2022-05-24) 59 | 60 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 61 | Please refer to the [WasmEdge 0.10.0](https://github.com/WasmEdge/WasmEdge/releases/tag/0.10.0) for more details. 62 | 63 | Breaking changes: 64 | 65 | * Renamed C API `WasmEdge_Tensorflow_ImportObjectCreate` to `WasmEdge_Tensorflow_ModuleInstanceCreate`. 66 | * Renamed C API `WasmEdge_Tensorflow_ImportObjectCreateDummy` to `WasmEdge_Tensorflow_ModuleInstanceCreateDummy`. 67 | * Renamed C API `WasmEdge_TensorflowLite_ImportObjectCreate` to `WasmEdge_TensorflowLite_ModuleInstanceCreate`. 68 | 69 | Features: 70 | 71 | * Update the `WasmEdge` dependency to `0.10.0`. 72 | * Added the Darwin x86_64 support. 73 | 74 | ### 0.9.1 (2022-02-10) 75 | 76 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 77 | Please refer to the [WasmEdge 0.9.1](https://github.com/WasmEdge/WasmEdge/releases/tag/0.9.1) for more details. 78 | 79 | Features: 80 | 81 | * Added the copyright text. 82 | * Update the `WasmEdge` dependency to `0.9.1`. 83 | * Added the Linux aarch64 support. 84 | * Added the Android aarch64 support. 85 | 86 | ### 0.9.0 (2021-12-09) 87 | 88 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 89 | Please refer to the [WasmEdge 0.9.0](https://github.com/WasmEdge/WasmEdge/releases/tag/0.9.0) for more details. 90 | 91 | Breaking changes: 92 | 93 | * Moved the C-API headers `wasmedge-tensorflow.h` and `wasmedge-tensorflowlite.h` into the `wasmedge` folder. 94 | 95 | Features: 96 | 97 | * Update the `WasmEdge` dependency to `0.9.0`. 98 | 99 | ### 0.8.2 (2021-09-06) 100 | 101 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 102 | Please refer to the [WasmEdge 0.8.2](https://github.com/WasmEdge/WasmEdge/releases/tag/0.8.2) for more details. 103 | 104 | Features: 105 | 106 | * Update the `WasmEdge` dependency to `0.8.2`. 107 | * Modified the CMake option `BUILD_SHARED_LIB` to `WASMEDGE_TENSORFLOW_BUILD_SHARED_LIB` for enabling compilation of the shared library (`ON` by default). 108 | 109 | ### 0.8.1 (2021-06-22) 110 | 111 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 112 | Please refer to the [WasmEdge 0.8.1](https://github.com/WasmEdge/WasmEdge/releases/tag/0.8.1) for more details. 113 | 114 | Features: 115 | 116 | * Update the `WasmEdge` dependency to `0.8.1`. 117 | 118 | ### 0.8.0 (2021-05-14) 119 | 120 | This is the host function extension for [WasmEdge](https://github.com/WasmEdge/WasmEdge). 121 | Please refer to the [WasmEdge 0.8.0](https://github.com/WasmEdge/WasmEdge/releases/tag/0.8.0) for more details. 122 | 123 | Features: 124 | 125 | * Renamed this project to `WasmEdge-tensorflow` and updated the `WasmEdge` dependency. 126 | * Added `wasmedge-tensorflow` and `wasmedge-tensorflowlite` C API shared library. 127 | * Added CMake option `BUILD_SHARED_LIB` to enable compiling the shared library (`ON` by default). 128 | * Added release CI. 129 | 130 | Tools: 131 | 132 | * Remove tools. The tools will be in the new [repository](https://github.com/second-state/WasmEdge-tensorflow-tools). 133 | 134 | ### 0.7.3 (2021-02-03) 135 | 136 | This is a extension release for updating `ssvm-core`. 137 | 138 | Features: 139 | 140 | * Update `ssvm-core` to version 0.7.3. 141 | * Please refer to the [SSVM 0.7.3](https://github.com/second-state/SSVM/releases/tag/0.7.3) for more details. 142 | 143 | Tools: 144 | 145 | * `download_dependencies_tf.sh` is the script to download and extract the required shared libraries of `libtensorflow` and `libtensorflow_framework`. 146 | * `download_dependencies_tflite.sh` is the script to download and extract the required shared libraries for only `ssvm-tensorflow-lite` tool. 147 | * `download_dependencies_all.sh` is the script to download and extract all the required shared libraries. 148 | 149 | ### 0.7.2 (2020-12-24) 150 | 151 | This is a extension release for updating `ssvm-core`. 152 | 153 | Features: 154 | 155 | * Update `ssvm-core` to version 0.7.2. 156 | * Please refer to the [SSVM 0.7.2](https://github.com/second-state/SSVM/releases/tag/0.7.2) for more details. 157 | 158 | ### 0.1.1 (2020-12-22) 159 | 160 | This is a extension release for the `ssvm-tensorflow-lite` tool. 161 | 162 | Tools: 163 | 164 | * `ssvm-tensorflow-lite` is the SSVM runner for executing WASM or compiled WASM with only tensorflow-lite extensions. 165 | * `download_dependencies_lite.sh` is the script to download and extract the required shared libraries for only `ssvm-tensorflow-lite` tool. 166 | 167 | ### 0.1.0 (2020-12-17) 168 | 169 | Features: 170 | 171 | * Image processing host function extensions of WASM 172 | * Support reading JPEG and PNG from buffer. 173 | * Support the rgb8 and rgb32f normalized formats. 174 | * Support image resizing. 175 | * TensorFlow and TensorFlow-Lite host function extension of WASM 176 | * Support creating TensorFlow and TensorFlow-Lite graphs from model buffer. 177 | * Support running models with input tensors. 178 | 179 | Tools: 180 | 181 | * `ssvmc-tensorflow` is the AOT compiler to compile WASM files into binaries. 182 | * `ssvm-tensorflow` is the SSVM runner for executing WASM or compiled WASM with tensorflow extensions. 183 | * `show-tflite-tensor` is the tool to list the input and output tensors information of a TensorFlow-Lite model. 184 | * `download_dependencies.sh` is the script to download and extract the required shared libraries. 185 | -------------------------------------------------------------------------------- /lib/tensorflow_func.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | // SPDX-FileCopyrightText: 2019-2022 Second State INC 3 | 4 | #include 5 | #include 6 | 7 | #include "tensorflow/c/c_api.h" 8 | 9 | #include "common/log.h" 10 | #include "common/span.h" 11 | #include "tensorflow_func.h" 12 | 13 | namespace WasmEdge { 14 | namespace Host { 15 | 16 | Expect 17 | WasmEdgeTensorflowCreateSession::body(const Runtime::CallingFrame &Frame, 18 | uint32_t ModBufPtr, uint32_t ModBufLen) { 19 | // Check memory instance from module. 20 | auto *MemInst = Frame.getMemoryByIndex(0); 21 | if (MemInst == nullptr) { 22 | return Unexpect(ErrCode::Value::HostFuncError); 23 | } 24 | 25 | // Create context and import graph. 26 | struct WasmEdgeTensorflowContext *Cxt = new WasmEdgeTensorflowContext(); 27 | Cxt->Graph = TF_NewGraph(); 28 | Cxt->Buffer = 29 | TF_NewBufferFromString(MemInst->getPointer(ModBufPtr), ModBufLen); 30 | Cxt->GraphOpts = TF_NewImportGraphDefOptions(); 31 | TF_GraphImportGraphDef(Cxt->Graph, Cxt->Buffer, Cxt->GraphOpts, Cxt->Stat); 32 | if (TF_GetCode(Cxt->Stat) != TF_OK) { 33 | spdlog::error( 34 | std::string( 35 | "wasmedge_tensorflow_create_session: Cannot import graph: ") + 36 | TF_Message(Cxt->Stat)); 37 | delete Cxt; 38 | return 0; 39 | } 40 | 41 | // Create session. 42 | Cxt->SessionOpts = TF_NewSessionOptions(); 43 | Cxt->Session = TF_NewSession(Cxt->Graph, Cxt->SessionOpts, Cxt->Stat); 44 | if (TF_GetCode(Cxt->Stat) != TF_OK) { 45 | spdlog::error( 46 | std::string( 47 | "wasmedge_tensorflow_create_session: Unable to create session: ") + 48 | TF_Message(Cxt->Stat)); 49 | delete Cxt; 50 | return 0; 51 | } 52 | return static_cast(reinterpret_cast(Cxt)); 53 | } 54 | 55 | Expect 56 | WasmEdgeTensorflowDeleteSession::body(const Runtime::CallingFrame &, 57 | uint64_t Cxt) { 58 | // Context struct 59 | auto *C = reinterpret_cast(Cxt); 60 | if (C != nullptr) { 61 | delete C; 62 | } 63 | return {}; 64 | } 65 | 66 | Expect 67 | WasmEdgeTensorflowRunSession::body(const Runtime::CallingFrame &, 68 | uint64_t Cxt) { 69 | // Context struct 70 | auto *C = reinterpret_cast(Cxt); 71 | 72 | // Delete old output tensors 73 | for (auto T : C->OutputTensors) { 74 | if (T) { 75 | TF_DeleteTensor(T); 76 | } 77 | } 78 | 79 | // Run session 80 | TF_SessionRun(C->Session, 81 | // RunOptions 82 | nullptr, 83 | // Input tensors 84 | &(C->Inputs[0]), &(C->InputTensors[0]), C->Inputs.size(), 85 | // Output tensors 86 | &(C->Outputs[0]), &(C->OutputTensors[0]), C->Outputs.size(), 87 | // Target operations 88 | nullptr, 0, 89 | // RunMetadata 90 | nullptr, 91 | // Output status 92 | C->Stat); 93 | 94 | if (TF_GetCode(C->Stat) != TF_OK) { 95 | spdlog::error( 96 | std::string( 97 | "wasmedge_tensorflow_run_session: Unable to run session: ") + 98 | TF_Message(C->Stat)); 99 | return 1; 100 | } 101 | return 0; 102 | } 103 | 104 | Expect 105 | WasmEdgeTensorflowGetOutputTensor::body(const Runtime::CallingFrame &Frame, 106 | uint64_t Cxt, uint32_t OutputPtr, 107 | uint32_t OutputLen, uint32_t Idx) { 108 | // Check memory instance from module. 109 | auto *MemInst = Frame.getMemoryByIndex(0); 110 | if (MemInst == nullptr) { 111 | return Unexpect(ErrCode::Value::HostFuncError); 112 | } 113 | 114 | // Context struct 115 | auto *C = reinterpret_cast(Cxt); 116 | 117 | // Find the output tensor 118 | std::string Name(MemInst->getPointer(OutputPtr), OutputLen); 119 | for (uint32_t I = 0; I < C->OutputNames.size(); ++I) { 120 | if (Name == C->OutputNames[I].first && Idx == C->OutputNames[I].second) { 121 | return static_cast( 122 | reinterpret_cast(C->OutputTensors[I])); 123 | } 124 | } 125 | return 0; 126 | } 127 | 128 | Expect 129 | WasmEdgeTensorflowGetTensorLen::body(const Runtime::CallingFrame &, 130 | uint64_t Tensor) { 131 | // Return tensor data length. 132 | TF_Tensor *T = reinterpret_cast(Tensor); 133 | if (T != nullptr) { 134 | return TF_TensorByteSize(T); 135 | } 136 | return 0; 137 | } 138 | 139 | Expect 140 | WasmEdgeTensorflowGetTensorData::body(const Runtime::CallingFrame &Frame, 141 | uint64_t Tensor, uint32_t BufPtr) { 142 | // Check memory instance from module. 143 | auto *MemInst = Frame.getMemoryByIndex(0); 144 | if (MemInst == nullptr) { 145 | return Unexpect(ErrCode::Value::HostFuncError); 146 | } 147 | 148 | // Copy tensor data to buffer. 149 | TF_Tensor *T = reinterpret_cast(Tensor); 150 | if (T != nullptr) { 151 | uint8_t *Data = static_cast(TF_TensorData(T)); 152 | uint8_t *Buf = MemInst->getPointer(BufPtr); 153 | if (TF_TensorByteSize(T) > 0) { 154 | std::copy_n(Data, TF_TensorByteSize(T), Buf); 155 | } 156 | } 157 | return {}; 158 | } 159 | 160 | Expect WasmEdgeTensorflowAppendInput::body( 161 | const Runtime::CallingFrame &Frame, uint64_t Cxt, uint32_t InputPtr, 162 | uint32_t InputLen, uint32_t Idx, uint32_t DimPtr, uint32_t DimCnt, 163 | uint32_t DataType, uint32_t TensorBufPtr, uint32_t TensorBufLen) { 164 | // Check memory instance from module. 165 | auto *MemInst = Frame.getMemoryByIndex(0); 166 | if (MemInst == nullptr) { 167 | return Unexpect(ErrCode::Value::HostFuncError); 168 | } 169 | 170 | // Context struct 171 | auto *C = reinterpret_cast(Cxt); 172 | 173 | // Allocate tensor and data copying 174 | TF_Tensor *Tensor = nullptr; 175 | if (DimCnt > 0) { 176 | Tensor = TF_AllocateTensor(static_cast(DataType), 177 | MemInst->getPointer(DimPtr), DimCnt, 178 | TensorBufLen); 179 | } else { 180 | Tensor = TF_AllocateTensor(static_cast(DataType), nullptr, 0, 181 | TensorBufLen); 182 | } 183 | if (Tensor != nullptr) { 184 | std::copy_n(MemInst->getPointer(TensorBufPtr), TensorBufLen, 185 | static_cast(TF_TensorData(Tensor))); 186 | } 187 | C->InputTensors.push_back(Tensor); 188 | 189 | // Store names and operations 190 | std::string Name(MemInst->getPointer(InputPtr), InputLen); 191 | C->InputNames.push_back({Name, Idx}); 192 | C->Inputs.emplace_back(TF_Output{ 193 | TF_GraphOperationByName(C->Graph, Name.c_str()), static_cast(Idx)}); 194 | return {}; 195 | } 196 | 197 | Expect 198 | WasmEdgeTensorflowAppendOutput::body(const Runtime::CallingFrame &Frame, 199 | uint64_t Cxt, uint32_t OutputPtr, 200 | uint32_t OutputLen, uint32_t Idx) { 201 | // Check memory instance from module. 202 | auto *MemInst = Frame.getMemoryByIndex(0); 203 | if (MemInst == nullptr) { 204 | return Unexpect(ErrCode::Value::HostFuncError); 205 | } 206 | 207 | // Context struct 208 | auto *C = reinterpret_cast(Cxt); 209 | std::string Name(MemInst->getPointer(OutputPtr), OutputLen); 210 | C->OutputTensors.push_back(nullptr); 211 | 212 | // Store names and operations 213 | C->OutputNames.push_back({Name, Idx}); 214 | C->Outputs.emplace_back(TF_Output{ 215 | TF_GraphOperationByName(C->Graph, Name.c_str()), static_cast(Idx)}); 216 | return {}; 217 | } 218 | 219 | Expect WasmEdgeTensorflowClearInput::body(const Runtime::CallingFrame &, 220 | uint64_t Cxt) { 221 | auto *C = reinterpret_cast(Cxt); 222 | C->Inputs.clear(); 223 | C->InputNames.clear(); 224 | for (auto T : C->InputTensors) { 225 | if (T) { 226 | TF_DeleteTensor(T); 227 | } 228 | } 229 | C->InputTensors.clear(); 230 | return {}; 231 | } 232 | 233 | Expect WasmEdgeTensorflowClearOutput::body(const Runtime::CallingFrame &, 234 | uint64_t Cxt) { 235 | auto *C = reinterpret_cast(Cxt); 236 | C->Outputs.clear(); 237 | C->OutputNames.clear(); 238 | for (auto T : C->OutputTensors) { 239 | if (T) { 240 | TF_DeleteTensor(T); 241 | } 242 | } 243 | C->OutputTensors.clear(); 244 | return {}; 245 | } 246 | 247 | } // namespace Host 248 | } // namespace WasmEdge 249 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | concurrency: 4 | group: release-${{ github.head_ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | push: 9 | tags: 10 | - "*" 11 | 12 | jobs: 13 | create: 14 | name: Create Release 15 | runs-on: ubuntu-latest 16 | container: 17 | image: wasmedge/wasmedge:ubuntu-build-gcc 18 | outputs: 19 | version: ${{ steps.prep.outputs.version }} 20 | upload_url: ${{ steps.create_release.outputs.upload_url }} 21 | steps: 22 | - name: Checkout code 23 | uses: actions/checkout@v3 24 | with: 25 | submodules: true 26 | - name: Get version 27 | id: prep 28 | run: | 29 | git config --global --add safe.directory $(pwd) 30 | echo ::set-output name=version::$(git describe --tag) 31 | - name: Create Release 32 | id: create_release 33 | uses: actions/create-release@v1 34 | env: 35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | with: 37 | tag_name: ${{ github.ref }} 38 | release_name: WasmEdge-TensorFlow ${{ steps.prep.outputs.version }} 39 | body_path: .CurrentChangelog.md 40 | draft: true 41 | prerelease: true 42 | 43 | build_and_upload_ubuntu: 44 | name: Ubuntu 20.04 x86_64 platform 45 | needs: create 46 | runs-on: ubuntu-latest 47 | container: 48 | image: wasmedge/wasmedge:ubuntu-build-clang 49 | steps: 50 | - name: Checkout code 51 | uses: actions/checkout@v3 52 | with: 53 | submodules: true 54 | - name: Build WasmEdge-tensorflow for Ubuntu 20.04 x86_64 55 | run: | 56 | git config --global --add safe.directory $(pwd) 57 | if ! cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release; then 58 | echo === CMakeOutput.log === 59 | cat build/CMakeFiles/CMakeOutput.log 60 | echo === CMakeError.log === 61 | cat build/CMakeFiles/CMakeError.log 62 | exit 1 63 | fi 64 | cmake --build build 65 | cd build 66 | tar -zcvf wasmedge-tf.tar.gz include/wasmedge/wasmedge-tensorflow.h lib/libwasmedge-tensorflow_c.so 67 | tar -zcvf wasmedge-tflite.tar.gz include/wasmedge/wasmedge-tensorflowlite.h lib/libwasmedge-tensorflowlite_c.so 68 | cd .. 69 | mv build/wasmedge-tf.tar.gz wasmedge-tf.tar.gz 70 | mv build/wasmedge-tflite.tar.gz wasmedge-tflite.tar.gz 71 | ls -alF 72 | - name: Upload WasmEdge-tensorflow Ubuntu 20.04 x86_64 tar.gz package 73 | uses: actions/upload-release-asset@v1 74 | env: 75 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 76 | with: 77 | upload_url: ${{ needs.create.outputs.upload_url }} 78 | asset_path: wasmedge-tf.tar.gz 79 | asset_name: WasmEdge-tensorflow-${{ needs.create.outputs.version }}-ubuntu20.04_x86_64.tar.gz 80 | asset_content_type: application/x-gzip 81 | - name: Upload WasmEdge-tensorflowlite Ubuntu 20.04 x86_64 tar.gz package 82 | uses: actions/upload-release-asset@v1 83 | env: 84 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 85 | with: 86 | upload_url: ${{ needs.create.outputs.upload_url }} 87 | asset_path: wasmedge-tflite.tar.gz 88 | asset_name: WasmEdge-tensorflowlite-${{ needs.create.outputs.version }}-ubuntu20.04_x86_64.tar.gz 89 | asset_content_type: application/x-gzip 90 | 91 | build_and_upload_manylinux2014_x86_64: 92 | name: Build WasmEdge-TensorFlow on manylinux2014_x86_64 platform 93 | needs: create 94 | runs-on: ubuntu-latest 95 | container: 96 | image: wasmedge/wasmedge:manylinux2014_x86_64 97 | steps: 98 | - name: Checkout code 99 | uses: actions/checkout@v3 100 | with: 101 | submodules: true 102 | - name: Build manylinux2014_x86_64 package 103 | run: | 104 | export PATH="/toolchain/bin:$PATH" 105 | export CC=gcc 106 | export CXX=g++ 107 | export CPPFLAGS=-I/toolchain/include 108 | export LDFLAGS=-L/toolchain/lib64 109 | curl -s -L -O --remote-name-all https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2 110 | echo "475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39 boost_1_79_0.tar.bz2" | sha256sum -c 111 | bzip2 -dc boost_1_79_0.tar.bz2 | tar -xf - 112 | if ! cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release -DBoost_NO_SYSTEM_PATHS=TRUE -DBOOST_INCLUDEDIR=$(pwd)/boost_1_79_0/; then 113 | echo === CMakeOutput.log === 114 | cat build/CMakeFiles/CMakeOutput.log 115 | echo === CMakeError.log === 116 | cat build/CMakeFiles/CMakeError.log 117 | exit 1 118 | fi 119 | cmake --build build 120 | cd build 121 | tar -zcvf wasmedge-tf.tar.gz include/wasmedge/wasmedge-tensorflow.h lib/libwasmedge-tensorflow_c.so 122 | tar Jcvf wasmedge-tf.tar.xz include/wasmedge/wasmedge-tensorflow.h lib/libwasmedge-tensorflow_c.so 123 | tar -zcvf wasmedge-tflite.tar.gz include/wasmedge/wasmedge-tensorflowlite.h lib/libwasmedge-tensorflowlite_c.so 124 | tar Jcvf wasmedge-tflite.tar.xz include/wasmedge/wasmedge-tensorflowlite.h lib/libwasmedge-tensorflowlite_c.so 125 | cd .. 126 | mv build/wasmedge-tf.tar.gz wasmedge-tf.tar.gz 127 | mv build/wasmedge-tf.tar.xz wasmedge-tf.tar.xz 128 | mv build/wasmedge-tflite.tar.gz wasmedge-tflite.tar.gz 129 | mv build/wasmedge-tflite.tar.xz wasmedge-tflite.tar.xz 130 | ls -alF 131 | - name: Upload WasmEdge-tensorflow manylinux2014_x86_64 tar.gz package 132 | uses: actions/upload-release-asset@v1 133 | env: 134 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 135 | with: 136 | upload_url: ${{ needs.create.outputs.upload_url }} 137 | asset_path: wasmedge-tf.tar.gz 138 | asset_name: WasmEdge-tensorflow-${{ needs.create.outputs.version }}-manylinux2014_x86_64.tar.gz 139 | asset_content_type: application/x-gzip 140 | - name: Upload WasmEdge-tensorflow manylinux2014_x86_64 tar.xz package 141 | uses: actions/upload-release-asset@v1 142 | env: 143 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 144 | with: 145 | upload_url: ${{ needs.create.outputs.upload_url }} 146 | asset_path: wasmedge-tf.tar.xz 147 | asset_name: WasmEdge-tensorflow-${{ needs.create.outputs.version }}-manylinux2014_x86_64.tar.xz 148 | asset_content_type: application/x-xz 149 | - name: Upload WasmEdge-tensorflowlite manylinux2014_x86_64 tar.gz package 150 | uses: actions/upload-release-asset@v1 151 | env: 152 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 153 | with: 154 | upload_url: ${{ needs.create.outputs.upload_url }} 155 | asset_path: wasmedge-tflite.tar.gz 156 | asset_name: WasmEdge-tensorflowlite-${{ needs.create.outputs.version }}-manylinux2014_x86_64.tar.gz 157 | asset_content_type: application/x-gzip 158 | - name: Upload WasmEdge-tensorflowlite manylinux2014_x86_64 tar.xz package 159 | uses: actions/upload-release-asset@v1 160 | env: 161 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 162 | with: 163 | upload_url: ${{ needs.create.outputs.upload_url }} 164 | asset_path: wasmedge-tflite.tar.xz 165 | asset_name: WasmEdge-tensorflowlite-${{ needs.create.outputs.version }}-manylinux2014_x86_64.tar.xz 166 | asset_content_type: application/x-xz 167 | 168 | build_and_upload_manylinux2014_aarch64: 169 | name: Build WasmEdge-TensorFlow on manylinux2014_aarch64 platform 170 | needs: create 171 | runs-on: linux-arm64 172 | container: 173 | image: wasmedge/wasmedge:manylinux2014_aarch64 174 | steps: 175 | - name: Checkout code 176 | uses: actions/checkout@v3 177 | with: 178 | submodules: true 179 | - name: Build manylinux2014_aarch64 package 180 | run: | 181 | export PATH="/toolchain/bin:$PATH" 182 | export CC=gcc 183 | export CXX=g++ 184 | export CPPFLAGS=-I/toolchain/include 185 | export LDFLAGS=-L/toolchain/lib64 186 | curl -s -L -O --remote-name-all https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2 187 | echo "475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39 boost_1_79_0.tar.bz2" | sha256sum -c 188 | bzip2 -dc boost_1_79_0.tar.bz2 | tar -xf - 189 | if ! cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release -DBoost_NO_SYSTEM_PATHS=TRUE -DBOOST_INCLUDEDIR=$(pwd)/boost_1_79_0/; then 190 | echo === CMakeOutput.log === 191 | cat build/CMakeFiles/CMakeOutput.log 192 | echo === CMakeError.log === 193 | cat build/CMakeFiles/CMakeError.log 194 | exit 1 195 | fi 196 | cmake --build build 197 | cd build 198 | tar -zcvf wasmedge-tflite.tar.gz include/wasmedge/wasmedge-tensorflowlite.h lib/libwasmedge-tensorflowlite_c.so 199 | tar Jcvf wasmedge-tflite.tar.xz include/wasmedge/wasmedge-tensorflowlite.h lib/libwasmedge-tensorflowlite_c.so 200 | cd .. 201 | mv build/wasmedge-tflite.tar.gz wasmedge-tflite.tar.gz 202 | mv build/wasmedge-tflite.tar.xz wasmedge-tflite.tar.xz 203 | ls -alF 204 | # Only tensorflow-lite has aarch64. 205 | - name: Upload WasmEdge-tensorflowlite manylinux2014_aarch64 tar.gz package 206 | uses: actions/upload-release-asset@v1 207 | env: 208 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 209 | with: 210 | upload_url: ${{ needs.create.outputs.upload_url }} 211 | asset_path: wasmedge-tflite.tar.gz 212 | asset_name: WasmEdge-tensorflowlite-${{ needs.create.outputs.version }}-manylinux2014_aarch64.tar.gz 213 | asset_content_type: application/x-gzip 214 | - name: Upload WasmEdge-tensorflowlite manylinux2014_aarch64 tar.xz package 215 | uses: actions/upload-release-asset@v1 216 | env: 217 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 218 | with: 219 | upload_url: ${{ needs.create.outputs.upload_url }} 220 | asset_path: wasmedge-tflite.tar.xz 221 | asset_name: WasmEdge-tensorflowlite-${{ needs.create.outputs.version }}-manylinux2014_aarch64.tar.xz 222 | asset_content_type: application/x-xz 223 | 224 | build_and_upload_darwin_x86_64: 225 | name: Darwin x86_64 platfrom 226 | needs: create 227 | runs-on: macos-11 228 | steps: 229 | - name: Checkout code 230 | uses: actions/checkout@v3 231 | with: 232 | submodules: true 233 | - name: Build WasmEdge-tensorflow for Darwin x86_64 234 | run: | 235 | brew install llvm ninja boost cmake 236 | export LLVM_DIR="/usr/local/opt/llvm/lib/cmake" 237 | export CC=clang 238 | export CXX=clang++ 239 | if ! cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release; then 240 | echo === CMakeOutput.log === 241 | cat build/CMakeFiles/CMakeOutput.log 242 | echo === CMakeError.log === 243 | cat build/CMakeFiles/CMakeError.log 244 | exit 1 245 | fi 246 | cmake --build build 247 | cd build 248 | tar -zcvf wasmedge-tf.tar.gz include/wasmedge/wasmedge-tensorflow.h lib/libwasmedge-tensorflow_c.dylib 249 | tar -zcvf wasmedge-tflite.tar.gz include/wasmedge/wasmedge-tensorflowlite.h lib/libwasmedge-tensorflowlite_c.dylib 250 | cd .. 251 | mv build/wasmedge-tf.tar.gz wasmedge-tf.tar.gz 252 | mv build/wasmedge-tflite.tar.gz wasmedge-tflite.tar.gz 253 | ls -alF 254 | - name: Upload WasmEdge-tensorflow darwin_x86_64 tar.gz package 255 | uses: actions/upload-release-asset@v1 256 | env: 257 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 258 | with: 259 | upload_url: ${{ needs.create.outputs.upload_url }} 260 | asset_path: wasmedge-tf.tar.gz 261 | asset_name: WasmEdge-tensorflow-${{ needs.create.outputs.version }}-darwin_x86_64.tar.gz 262 | asset_content_type: application/x-gzip 263 | - name: Upload WasmEdge-tensorflowlite darwin_x86_64 tar.gz package 264 | uses: actions/upload-release-asset@v1 265 | env: 266 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 267 | with: 268 | upload_url: ${{ needs.create.outputs.upload_url }} 269 | asset_path: wasmedge-tflite.tar.gz 270 | asset_name: WasmEdge-tensorflowlite-${{ needs.create.outputs.version }}-darwin_x86_64.tar.gz 271 | asset_content_type: application/x-gzip 272 | 273 | build_and_upload_android: 274 | name: Android platforms 275 | needs: create 276 | runs-on: ubuntu-latest 277 | container: 278 | image: wasmedge/wasmedge:latest 279 | steps: 280 | - name: Checkout code 281 | uses: actions/checkout@v3 282 | with: 283 | submodules: true 284 | - name: Install dependency 285 | run: | 286 | apt update && apt install -y unzip 287 | apt remove -y cmake 288 | curl -sLO https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz 289 | tar -zxf cmake-3.22.2-linux-x86_64.tar.gz 290 | cp -r cmake-3.22.2-linux-x86_64/bin /usr/local 291 | cp -r cmake-3.22.2-linux-x86_64/share /usr/local 292 | curl -sLO https://dl.google.com/android/repository/android-ndk-r23b-linux.zip 293 | unzip -q android-ndk-r23b-linux.zip 294 | - name: Build WasmEdge-tensorflow for Android 295 | run: | 296 | export ANDROID_NDK_HOME=$(pwd)/android-ndk-r23b/ 297 | if ! cmake -Bbuild -GNinja -DCMAKE_BUILD_TYPE=Release -DWASMEDGE_BUILD_AOT_RUNTIME=OFF -DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=23 -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a -DCMAKE_ANDROID_NDK=$ANDROID_NDK_HOME -DCMAKE_ANDROID_STL_TYPE=c++_static; then 298 | echo === CMakeOutput.log === 299 | cat build/CMakeFiles/CMakeOutput.log 300 | echo === CMakeError.log === 301 | cat build/CMakeFiles/CMakeError.log 302 | exit 1 303 | fi 304 | cmake --build build 305 | cd build 306 | tar -zcvf wasmedge-tflite.tar.gz include/wasmedge/wasmedge-tensorflowlite.h lib/libwasmedge-tensorflowlite_c.so 307 | cd .. 308 | mv build/wasmedge-tflite.tar.gz wasmedge-tflite.tar.gz 309 | ls -alF 310 | - name: Upload WasmEdge-tensorflowlite android_aarch64 tar.gz package 311 | uses: actions/upload-release-asset@v1 312 | env: 313 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 314 | with: 315 | upload_url: ${{ needs.create.outputs.upload_url }} 316 | asset_path: wasmedge-tflite.tar.gz 317 | asset_name: WasmEdge-tensorflowlite-${{ needs.create.outputs.version }}-android_aarch64.tar.gz 318 | asset_content_type: application/x-gzip 319 | --------------------------------------------------------------------------------