forked from mindspore-Ecosystem/mindspore
add quick start demo
This commit is contained in:
parent
1252250d7e
commit
4ed332f28f
|
@ -0,0 +1,21 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
project(QuickStartCpp)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3.0)
|
||||
message(FATAL_ERROR "GCC version ${CMAKE_CXX_COMPILER_VERSION} must not be less than 7.3.0")
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
file(GLOB_RECURSE QUICK_START_CXX ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
add_library(mindspore-lite STATIC IMPORTED)
|
||||
set_target_properties(mindspore-lite PROPERTIES IMPORTED_LOCATION
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lib/libmindspore-lite.a)
|
||||
|
||||
add_executable(mindspore_quick_start_cpp ${QUICK_START_CXX})
|
||||
|
||||
target_link_libraries(
|
||||
mindspore_quick_start_cpp
|
||||
-Wl,--whole-archive mindspore-lite -Wl,--no-whole-archive
|
||||
pthread
|
||||
)
|
|
@ -0,0 +1,43 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 Huawei Technologies Co., Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ============================================================================
|
||||
|
||||
BASEPATH=$(cd "$(dirname $0)"; pwd)
|
||||
get_version() {
|
||||
VERSION_MAJOR=$(grep "const int ms_version_major =" ${BASEPATH}/../../include/version.h | tr -dc "[0-9]")
|
||||
VERSION_MINOR=$(grep "const int ms_version_minor =" ${BASEPATH}/../../include/version.h | tr -dc "[0-9]")
|
||||
VERSION_REVISION=$(grep "const int ms_version_revision =" ${BASEPATH}/../../include/version.h | tr -dc "[0-9]")
|
||||
VERSION_STR=${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}
|
||||
}
|
||||
get_version
|
||||
MODEL_DOWNLOAD_URL="https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/1.1/mobilenetv2.ms"
|
||||
MINDSPORE_LITE_DOWNLOAD_URL="https://ms-release.obs.cn-north-4.myhuaweicloud.com/${VERSION_STR}/MindSpore/lite/release/linux/mindspore-lite-${VERSION_STR}-inference-linux-x64.tar.gz"
|
||||
|
||||
mkdir -p build
|
||||
mkdir -p lib
|
||||
mkdir -p model
|
||||
if [ ! -e ${BASEPATH}/model/mobilenetv2.ms ]; then
|
||||
wget -c -O ${BASEPATH}/model/mobilenetv2.ms --no-check-certificate ${MODEL_DOWNLOAD_URL}
|
||||
fi
|
||||
if [ ! -e ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-linux-x64.tar.gz ]; then
|
||||
wget -c -O ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-linux-x64.tar.gz --no-check-certificate ${MINDSPORE_LITE_DOWNLOAD_URL}
|
||||
fi
|
||||
tar xzvf ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-linux-x64.tar.gz -C ${BASEPATH}/build/
|
||||
cp -r ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-linux-x64-avx/lib/libmindspore-lite.a ${BASEPATH}/lib
|
||||
cp -r ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-linux-x64-avx/include ${BASEPATH}/
|
||||
|
||||
cd ${BASEPATH}/build
|
||||
cmake ${BASEPATH}
|
||||
make
|
|
@ -0,0 +1,179 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include "include/errorcode.h"
|
||||
#include "include/model.h"
|
||||
#include "include/context.h"
|
||||
#include "include/lite_session.h"
|
||||
|
||||
char *ReadFile(const char *file, size_t *size) {
|
||||
if (file == nullptr) {
|
||||
std::cerr << "file is nullptr." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::ifstream ifs(file);
|
||||
if (!ifs.good()) {
|
||||
std::cerr << "file: " << file << " is not exist." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ifs.is_open()) {
|
||||
std::cerr << "file: " << file << " open failed." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ifs.seekg(0, std::ios::end);
|
||||
*size = ifs.tellg();
|
||||
std::unique_ptr<char[]> buf(new (std::nothrow) char[*size]);
|
||||
if (buf == nullptr) {
|
||||
std::cerr << "malloc buf failed, file: " << file << std::endl;
|
||||
ifs.close();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
ifs.read(buf.get(), *size);
|
||||
ifs.close();
|
||||
|
||||
return buf.release();
|
||||
}
|
||||
|
||||
template <typename T, typename Distribution>
|
||||
void GenerateRandomData(int size, void *data, Distribution distribution) {
|
||||
std::mt19937 random_engine;
|
||||
int elements_num = size / sizeof(T);
|
||||
(void)std::generate_n(static_cast<T *>(data), elements_num,
|
||||
[&]() { return static_cast<T>(distribution(random_engine)); });
|
||||
}
|
||||
|
||||
int GenerateInputDataWithRandom(std::vector<mindspore::tensor::MSTensor *> inputs) {
|
||||
for (auto tensor : inputs) {
|
||||
auto input_data = tensor->MutableData();
|
||||
void *random_data = malloc(tensor->Size());
|
||||
if (input_data == nullptr) {
|
||||
std::cerr << "MallocData for inTensor failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
GenerateRandomData<float>(tensor->Size(), random_data, std::uniform_real_distribution<float>(0.1f, 1.0f));
|
||||
// Copy data to input tensor.
|
||||
memcpy(input_data, random_data, tensor->Size());
|
||||
}
|
||||
return mindspore::lite::RET_OK;
|
||||
}
|
||||
|
||||
int Run(mindspore::session::LiteSession *session) {
|
||||
auto inputs = session->GetInputs();
|
||||
auto ret = GenerateInputDataWithRandom(inputs);
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
std::cerr << "Generate Random Input Data failed." << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = session->RunGraph();
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
std::cerr << "Inference error " << ret << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto out_tensors = session->GetOutputs();
|
||||
for (auto tensor : out_tensors) {
|
||||
std::cout << "tensor name is:" << tensor.first << " tensor size is:" << tensor.second->Size()
|
||||
<< " tensor elements num is:" << tensor.second->ElementsNum() << std::endl;
|
||||
auto out_data = reinterpret_cast<float *>(tensor.second->MutableData());
|
||||
std::cout << "output data is:";
|
||||
for (int i = 0; i < tensor.second->ElementsNum() && i <= 50; i++) {
|
||||
std::cout << out_data[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
return mindspore::lite::RET_OK;
|
||||
}
|
||||
|
||||
mindspore::session::LiteSession *Compile(mindspore::lite::Model *model) {
|
||||
// Create and init context.
|
||||
auto context = std::make_shared<mindspore::lite::Context>();
|
||||
if (context == nullptr) {
|
||||
std::cerr << "New context failed while." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create the session.
|
||||
mindspore::session::LiteSession *session = mindspore::session::LiteSession::CreateSession(context.get());
|
||||
if (session == nullptr) {
|
||||
std::cerr << "CreateSession failed while running." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Compile graph.
|
||||
auto ret = session->CompileGraph(model);
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
std::cerr << "Compile failed while running." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Note: when use model->Free(), the model can not be compiled again.
|
||||
if (model != nullptr) {
|
||||
model->Free();
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
int CompileAndRun(int argc, const char **argv) {
|
||||
if (argc < 2) {
|
||||
std::cerr << "Usage: ./mindspore_quick_start_cpp ../model/mobilenetv2.ms\n";
|
||||
return -1;
|
||||
}
|
||||
// Read model file.
|
||||
auto model_path = argv[1];
|
||||
size_t size = 0;
|
||||
char *model_buf = ReadFile(model_path, &size);
|
||||
if (model_buf == nullptr) {
|
||||
std::cerr << "Read model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Load the .ms model.
|
||||
auto model = mindspore::lite::Model::Import(model_buf, size);
|
||||
delete[](model_buf);
|
||||
if (model == nullptr) {
|
||||
std::cerr << "Import model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Compile MindSpore Lite model.
|
||||
auto session = Compile(model);
|
||||
if (session == nullptr) {
|
||||
std::cerr << "Create session failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Run inference.
|
||||
auto ret = Run(session);
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
std::cerr << "MindSpore Lite run failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Delete model buffer.
|
||||
delete model;
|
||||
// Delete session buffer.
|
||||
delete session;
|
||||
return mindspore::lite::RET_OK;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) { return CompileAndRun(argc, argv); }
|
|
@ -0,0 +1,48 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
project(RuntimeCpp)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.3.0)
|
||||
message(FATAL_ERROR "GCC version ${CMAKE_CXX_COMPILER_VERSION} must not be less than 7.3.0")
|
||||
endif()
|
||||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
file(GLOB_RECURSE RUNTIME_CPP ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
|
||||
|
||||
add_executable(runtime_cpp ${RUNTIME_CPP})
|
||||
find_library(log-lib log)
|
||||
target_link_libraries(
|
||||
runtime_cpp
|
||||
-Wl,--whole-archive mindspore-lite -Wl,--no-whole-archive
|
||||
hiai
|
||||
hiai_ir
|
||||
hiai_ir_build
|
||||
${log-lib}
|
||||
)
|
||||
|
||||
SET(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/build/tmp)
|
||||
|
||||
INSTALL(TARGETS runtime_cpp
|
||||
DESTINATION exe)
|
||||
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/lib/libhiai.so
|
||||
DESTINATION lib)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/lib/libhiai_ir.so
|
||||
DESTINATION lib)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/lib/libhiai_ir_build.so
|
||||
DESTINATION lib)
|
||||
INSTALL(FILES
|
||||
${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so
|
||||
DESTINATION lib)
|
||||
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/model/mobilenetv2.ms
|
||||
DESTINATION model)
|
||||
|
||||
set(CPACK_GENERATOR "TGZ")
|
||||
|
||||
set(CPACK_PACKAGE_FILE_NAME "runtime_cpp_demo")
|
||||
|
||||
set(CPACK_PACKAGE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/output)
|
||||
|
||||
include(CPack)
|
|
@ -0,0 +1,55 @@
|
|||
## 构建与运行
|
||||
|
||||
- 环境要求
|
||||
- 系统环境:Linux x86_64,推荐使用Ubuntu 18.04.02LTS
|
||||
- 编译依赖:
|
||||
- [CMake](https://cmake.org/download/) >= 3.18.3
|
||||
- [GCC](https://gcc.gnu.org/releases.html) >= 7.3.0
|
||||
- [Android_NDK](https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip) >= r20
|
||||
- [Git](https://git-scm.com/downloads) >= 2.28.0
|
||||
|
||||
- 编译构建
|
||||
|
||||
在`mindspore/lite/examples/runtime_cpp`目录下执行build脚本,将能够自动下载相关文件并编译Demo。
|
||||
|
||||
```bash
|
||||
bash build.sh
|
||||
```
|
||||
|
||||
> 若MindSpore Lite推理框架下载失败,请手动下载硬件平台为CPU,操作系统为Ubuntu-x64的[MindSpore Lite 模型推理框架](https://www.mindspore.cn/tutorial/lite/zh-CN/r1.1/use/downloads.html),解压后将其拷贝对应到`mindspore/lite/examples/runtime_cpp/lib`目录。
|
||||
>
|
||||
> 若mobilenetv2模型下载失败,请手动下载相关模型文件[mobilenetv2](https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2.ms),并将其拷贝到`mindspore/lite/examples/runtime_cpp/model`目录。
|
||||
|
||||
- 文件传输
|
||||
|
||||
使用`adb`将`mindspore/lite/examples/runtime_cpp\output`目录下的`runtime_cpp_demo.tar.gz`压缩包发送到Android手机
|
||||
|
||||
```shell
|
||||
adb push runtime_cpp_demo.tar.gz /data/local/tmp
|
||||
```
|
||||
|
||||
- 执行推理
|
||||
|
||||
使用`adb`进入Android Shell命令模式
|
||||
|
||||
```shell
|
||||
adb shell
|
||||
```
|
||||
|
||||
进入压缩包所在的相关目录,并进行解压
|
||||
|
||||
```shell
|
||||
cd /data/local/tmp && tar xzvf runtime_cpp_demo.tar.gz
|
||||
```
|
||||
|
||||
配置`LD_LIBRARY_PATH`环境变量
|
||||
|
||||
```shell
|
||||
export LD_LIBRARY_PATH = /data/local/tmp/runtime_cpp_demo/lib:{LD_LIBRARY_PATH}
|
||||
```
|
||||
|
||||
编译构建后,进入`mindspore/lite/examples/runtime_cpp/build`目录,并执行以下命令,体验MindSpore Lite推理mobilenetv2模型。
|
||||
|
||||
```bash
|
||||
./runtime_cpp ../model/mobilenetv2.ms 0
|
||||
```
|
|
@ -0,0 +1,49 @@
|
|||
#!/bin/bash
|
||||
# Copyright 2021 Huawei Technologies Co., Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ============================================================================
|
||||
|
||||
BASEPATH=$(
|
||||
cd "$(dirname $0)"
|
||||
pwd
|
||||
)
|
||||
get_version() {
|
||||
VERSION_MAJOR=$(grep "const int ms_version_major =" ${BASEPATH}/../../include/version.h | tr -dc "[0-9]")
|
||||
VERSION_MINOR=$(grep "const int ms_version_minor =" ${BASEPATH}/../../include/version.h | tr -dc "[0-9]")
|
||||
VERSION_REVISION=$(grep "const int ms_version_revision =" ${BASEPATH}/../../include/version.h | tr -dc "[0-9]")
|
||||
VERSION_STR=${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}
|
||||
}
|
||||
get_version
|
||||
MODEL_DOWNLOAD_URL="https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/1.1/mobilenetv2.ms"
|
||||
MINDSPORE_LITE_DOWNLOAD_URL="https://ms-release.obs.cn-north-4.myhuaweicloud.com/${VERSION_STR}/MindSpore/lite/release/android/mindspore-lite-${VERSION_STR}-inference-android.tar.gz"
|
||||
|
||||
mkdir -p build
|
||||
mkdir -p lib
|
||||
mkdir -p model
|
||||
if [ ! -e ${BASEPATH}/model/mobilenetv2.ms ]; then
|
||||
wget -c -O ${BASEPATH}/model/mobilenetv2.ms --no-check-certificate ${MODEL_DOWNLOAD_URL}
|
||||
fi
|
||||
if [ ! -e ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-android.tar.gz ]; then
|
||||
wget -c -O ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-android.tar.gz --no-check-certificate ${MINDSPORE_LITE_DOWNLOAD_URL}
|
||||
fi
|
||||
tar xzvf ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-android.tar.gz -C ${BASEPATH}/build/
|
||||
cp -r ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-android/lib/aarch64/libmindspore-lite.a ${BASEPATH}/lib
|
||||
cp -r ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-android/third_party/hiai_ddk/lib/aarch64/*.so ${BASEPATH}/lib
|
||||
cp -r ${BASEPATH}/build/mindspore-lite-${VERSION_STR}-inference-android/include ${BASEPATH}/
|
||||
|
||||
cd ${BASEPATH}/build
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK}/build/cmake/android.toolchain.cmake" -DANDROID_NATIVE_API_LEVEL="19" \
|
||||
-DANDROID_NDK="${ANDROID_NDK}" -DANDROID_ABI="arm64-v8a" -DANDROID_STL="c++_shared" ${BASEPATH}
|
||||
|
||||
make && make install && make package
|
|
@ -0,0 +1,699 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <random>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
#include "include/errorcode.h"
|
||||
#include "include/model.h"
|
||||
#include "include/context.h"
|
||||
#include "include/lite_session.h"
|
||||
#include "include/version.h"
|
||||
|
||||
char *ReadFile(const char *file, size_t *size) {
|
||||
if (file == nullptr) {
|
||||
std::cerr << "file is nullptr." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::ifstream ifs(file);
|
||||
if (!ifs.good()) {
|
||||
std::cerr << "file: " << file << " is not exist." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ifs.is_open()) {
|
||||
std::cerr << "file: " << file << " open failed." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ifs.seekg(0, std::ios::end);
|
||||
*size = ifs.tellg();
|
||||
std::unique_ptr<char[]> buf(new (std::nothrow) char[*size]);
|
||||
if (buf == nullptr) {
|
||||
std::cerr << "malloc buf failed, file: " << file << std::endl;
|
||||
ifs.close();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
ifs.read(buf.get(), *size);
|
||||
ifs.close();
|
||||
|
||||
return buf.release();
|
||||
}
|
||||
|
||||
template <typename T, typename Distribution>
|
||||
void GenerateRandomData(int size, void *data, Distribution distribution) {
|
||||
if (data == nullptr) {
|
||||
std::cerr << "data is nullptr." << std::endl;
|
||||
return;
|
||||
}
|
||||
std::mt19937 random_engine;
|
||||
int elements_num = size / sizeof(T);
|
||||
(void)std::generate_n(static_cast<T *>(data), elements_num,
|
||||
[&]() { return static_cast<T>(distribution(random_engine)); });
|
||||
}
|
||||
|
||||
std::shared_ptr<mindspore::lite::Context> CreateCPUContext() {
|
||||
auto context = std::make_shared<mindspore::lite::Context>();
|
||||
if (context == nullptr) {
|
||||
std::cerr << "New context failed while running." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
// CPU device context has default values.
|
||||
auto &cpu_device_info = context->device_list_[0].device_info_.cpu_device_info_;
|
||||
// The large core takes priority in thread and core binding methods. This parameter will work in the BindThread
|
||||
// interface. For specific binding effect, see the "Run Graph" section.
|
||||
cpu_device_info.cpu_bind_mode_ = mindspore::lite::HIGHER_CPU;
|
||||
// Use float16 operator as priority.
|
||||
cpu_device_info.enable_float16_ = true;
|
||||
return context;
|
||||
}
|
||||
|
||||
std::shared_ptr<mindspore::lite::Context> CreateGPUContext() {
|
||||
auto context = std::make_shared<mindspore::lite::Context>();
|
||||
if (context == nullptr) {
|
||||
std::cerr << "New context failed while running. " << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If GPU device context is set. The preferred backend is GPU, which means, if there is a GPU operator, it will run on
|
||||
// the GPU first, otherwise it will run on the CPU.
|
||||
mindspore::lite::DeviceContext gpu_device_ctx{mindspore::lite::DT_GPU, {false}};
|
||||
// GPU use float16 operator as priority.
|
||||
gpu_device_ctx.device_info_.gpu_device_info_.enable_float16_ = true;
|
||||
// The GPU device context needs to be push_back into device_list to work.
|
||||
context->device_list_.push_back(gpu_device_ctx);
|
||||
return context;
|
||||
}
|
||||
|
||||
std::shared_ptr<mindspore::lite::Context> CreateNPUContext() {
|
||||
auto context = std::make_shared<mindspore::lite::Context>();
|
||||
if (context == nullptr) {
|
||||
std::cerr << "New context failed while running. " << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
mindspore::lite::DeviceContext npu_device_ctx{mindspore::lite::DT_NPU};
|
||||
npu_device_ctx.device_info_.npu_device_info_.frequency_ = 3;
|
||||
// The NPU device context needs to be push_back into device_list to work.
|
||||
context->device_list_.push_back(npu_device_ctx);
|
||||
return context;
|
||||
}
|
||||
|
||||
int GetInputsAndSetData(mindspore::session::LiteSession *session) {
|
||||
auto inputs = session->GetInputs();
|
||||
|
||||
// The model has only one input tensor.
|
||||
auto in_tensor = inputs.front();
|
||||
if (in_tensor == nullptr) {
|
||||
std::cerr << "Input tensor is nullptr" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
auto input_data = in_tensor->MutableData();
|
||||
if (input_data == nullptr) {
|
||||
std::cerr << "MallocData for inTensor failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
GenerateRandomData<float>(in_tensor->Size(), input_data, std::uniform_real_distribution<float>(0.1f, 1.0f));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetInputsByTensorNameAndSetData(mindspore::session::LiteSession *session) {
|
||||
auto in_tensor = session->GetInputsByTensorName("2029_2028_1_construct_wrapper:x");
|
||||
if (in_tensor == nullptr) {
|
||||
std::cerr << "Input tensor is nullptr" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
auto input_data = in_tensor->MutableData();
|
||||
if (input_data == nullptr) {
|
||||
std::cerr << "MallocData for inTensor failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
GenerateRandomData<float>(in_tensor->Size(), input_data, std::uniform_real_distribution<float>(0.1f, 1.0f));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GetOutputsByNodeName(mindspore::session::LiteSession *session) {
|
||||
// model has a output node named output_node_name_0.
|
||||
auto output_vec = session->GetOutputsByNodeName("Default/Sigmoid-op204");
|
||||
// output node named output_node_name_0 has only one output tensor.
|
||||
auto out_tensor = output_vec.front();
|
||||
if (out_tensor == nullptr) {
|
||||
std::cerr << "Output tensor is nullptr" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "tensor size is:" << out_tensor->Size() << " tensor elements num is:" << out_tensor->ElementsNum()
|
||||
<< std::endl;
|
||||
// The model output data is float 32.
|
||||
if (out_tensor->data_type() != mindspore::TypeId::kNumberTypeFloat32) {
|
||||
std::cerr << "Output should in float32" << std::endl;
|
||||
return;
|
||||
}
|
||||
auto out_data = reinterpret_cast<float *>(out_tensor->MutableData());
|
||||
if (out_data == nullptr) {
|
||||
std::cerr << "Data of out_tensor is nullptr" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "output data is:";
|
||||
for (int i = 0; i < out_tensor->ElementsNum() && i < 10; i++) {
|
||||
std::cout << out_data[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void GetOutputByTensorName(mindspore::session::LiteSession *session) {
|
||||
// We can use GetOutputTensorNames method to get all name of output tensor of model which is in order.
|
||||
auto tensor_names = session->GetOutputTensorNames();
|
||||
// Use output tensor name returned by GetOutputTensorNames as key
|
||||
for (const auto &tensor_name : tensor_names) {
|
||||
auto out_tensor = session->GetOutputByTensorName(tensor_name);
|
||||
if (out_tensor == nullptr) {
|
||||
std::cerr << "Output tensor is nullptr" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "tensor size is:" << out_tensor->Size() << " tensor elements num is:" << out_tensor->ElementsNum()
|
||||
<< std::endl;
|
||||
// The model output data is float 32.
|
||||
if (out_tensor->data_type() != mindspore::TypeId::kNumberTypeFloat32) {
|
||||
std::cerr << "Output should in float32" << std::endl;
|
||||
return;
|
||||
}
|
||||
auto out_data = reinterpret_cast<float *>(out_tensor->MutableData());
|
||||
if (out_data == nullptr) {
|
||||
std::cerr << "Data of out_tensor is nullptr" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "output data is:";
|
||||
for (int i = 0; i < out_tensor->ElementsNum() && i < 10; i++) {
|
||||
std::cout << out_data[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void GetOutputs(mindspore::session::LiteSession *session) {
|
||||
auto out_tensors = session->GetOutputs();
|
||||
for (auto out_tensor : out_tensors) {
|
||||
std::cout << "tensor name is:" << out_tensor.first << " tensor size is:" << out_tensor.second->Size()
|
||||
<< " tensor elements num is:" << out_tensor.second->ElementsNum() << std::endl;
|
||||
// The model output data is float 32.
|
||||
if (out_tensor.second->data_type() != mindspore::TypeId::kNumberTypeFloat32) {
|
||||
std::cerr << "Output should in float32" << std::endl;
|
||||
return;
|
||||
}
|
||||
auto out_data = reinterpret_cast<float *>(out_tensor.second->MutableData());
|
||||
if (out_data == nullptr) {
|
||||
std::cerr << "Data of out_tensor is nullptr" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "output data is:";
|
||||
for (int i = 0; i < out_tensor.second->ElementsNum() && i < 10; i++) {
|
||||
std::cout << out_data[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
mindspore::session::LiteSession *CreateSessionAndCompileByModel(mindspore::lite::Model *model) {
|
||||
// Create and init CPU context.
|
||||
// If you need to use GPU or NPU, you can refer to CreateGPUContext() or CreateNPUContext().
|
||||
auto context = CreateCPUContext();
|
||||
if (context == nullptr) {
|
||||
std::cerr << "New context failed while." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create the session.
|
||||
mindspore::session::LiteSession *session = mindspore::session::LiteSession::CreateSession(context.get());
|
||||
if (session == nullptr) {
|
||||
std::cerr << "CreateSession failed while running." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Compile graph.
|
||||
auto ret = session->CompileGraph(model);
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
delete session;
|
||||
std::cerr << "Compile failed while running." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
mindspore::session::LiteSession *CreateSessionAndCompileByModelBuffer(char *model_buf, size_t size) {
|
||||
auto context = std::make_shared<mindspore::lite::Context>();
|
||||
if (context == nullptr) {
|
||||
std::cerr << "New context failed while running" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
// Use model buffer and context to create Session.
|
||||
auto session = mindspore::session::LiteSession::CreateSession(model_buf, size, context.get());
|
||||
if (session == nullptr) {
|
||||
std::cerr << "CreateSession failed while running" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
int ResizeInputsTensorShape(mindspore::session::LiteSession *session) {
|
||||
auto inputs = session->GetInputs();
|
||||
std::vector<int> resize_shape = {1, 128, 128, 3};
|
||||
// Assume the model has only one input,resize input shape to [1, 128, 128, 3]
|
||||
std::vector<std::vector<int>> new_shapes;
|
||||
new_shapes.push_back(resize_shape);
|
||||
return session->Resize(inputs, new_shapes);
|
||||
}
|
||||
|
||||
int Run(const char *model_path) {
|
||||
// Read model file.
|
||||
size_t size = 0;
|
||||
char *model_buf = ReadFile(model_path, &size);
|
||||
if (model_buf == nullptr) {
|
||||
std::cerr << "Read model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Load the .ms model.
|
||||
auto model = mindspore::lite::Model::Import(model_buf, size);
|
||||
delete[](model_buf);
|
||||
if (model == nullptr) {
|
||||
std::cerr << "Import model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Compile MindSpore Lite model.
|
||||
auto session = CreateSessionAndCompileByModel(model);
|
||||
if (session == nullptr) {
|
||||
delete model;
|
||||
std::cerr << "Create session failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Note: when use model->Free(), the model can not be compiled again.
|
||||
model->Free();
|
||||
|
||||
// Set inputs data.
|
||||
// You can also get input through other methods, and you can refer to GetInputsAndSetData()
|
||||
GetInputsByTensorNameAndSetData(session);
|
||||
|
||||
session->BindThread(true);
|
||||
auto ret = session->RunGraph();
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
delete model;
|
||||
std::cerr << "Inference error " << ret << std::endl;
|
||||
return ret;
|
||||
}
|
||||
session->BindThread(false);
|
||||
|
||||
// Get outputs data.
|
||||
// You can also get output through other methods,
|
||||
// and you can refer to GetOutputByTensorName() or GetOutputs().
|
||||
GetOutputsByNodeName(session);
|
||||
|
||||
// Delete model buffer.
|
||||
delete model;
|
||||
// Delete session buffer.
|
||||
delete session;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RunResize(const char *model_path) {
|
||||
size_t size = 0;
|
||||
char *model_buf = ReadFile(model_path, &size);
|
||||
if (model_buf == nullptr) {
|
||||
std::cerr << "Read model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Load the .ms model.
|
||||
auto model = mindspore::lite::Model::Import(model_buf, size);
|
||||
delete[](model_buf);
|
||||
if (model == nullptr) {
|
||||
std::cerr << "Import model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Compile MindSpore Lite model.
|
||||
auto session = CreateSessionAndCompileByModel(model);
|
||||
if (session == nullptr) {
|
||||
delete model;
|
||||
std::cerr << "Create session failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Resize inputs tensor shape.
|
||||
auto ret = ResizeInputsTensorShape(session);
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
delete model;
|
||||
std::cerr << "Resize input tensor shape error." << ret << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Set inputs data.
|
||||
// You can also get input through other methods, and you can refer to GetInputsAndSetData()
|
||||
GetInputsByTensorNameAndSetData(session);
|
||||
|
||||
session->BindThread(true);
|
||||
ret = session->RunGraph();
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
delete model;
|
||||
std::cerr << "Inference error " << ret << std::endl;
|
||||
return ret;
|
||||
}
|
||||
session->BindThread(false);
|
||||
|
||||
// Get outputs data.
|
||||
// You can also get output through other methods,
|
||||
// and you can refer to GetOutputByTensorName() or GetOutputs().
|
||||
GetOutputsByNodeName(session);
|
||||
|
||||
// Delete model buffer.
|
||||
delete model;
|
||||
// Delete session buffer.
|
||||
delete session;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RunCreateSessionSimplified(const char *model_path) {
|
||||
size_t size = 0;
|
||||
char *model_buf = ReadFile(model_path, &size);
|
||||
if (model_buf == nullptr) {
|
||||
std::cerr << "Read model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Compile MindSpore Lite model.
|
||||
auto session = CreateSessionAndCompileByModelBuffer(model_buf, size);
|
||||
if (session == nullptr) {
|
||||
std::cerr << "Create session failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set inputs data.
|
||||
// You can also get input through other methods, and you can refer to GetInputsAndSetData()
|
||||
GetInputsByTensorNameAndSetData(session);
|
||||
|
||||
session->BindThread(true);
|
||||
auto ret = session->RunGraph();
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
std::cerr << "Inference error " << ret << std::endl;
|
||||
return ret;
|
||||
}
|
||||
session->BindThread(false);
|
||||
|
||||
// Get outputs data.
|
||||
// You can also get output through other methods,
|
||||
// and you can refer to GetOutputByTensorName() or GetOutputs().
|
||||
GetOutputsByNodeName(session);
|
||||
|
||||
// Delete session buffer.
|
||||
delete session;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RunSessionParallel(const char *model_path) {
|
||||
size_t size = 0;
|
||||
char *model_buf = ReadFile(model_path, &size);
|
||||
if (model_buf == nullptr) {
|
||||
std::cerr << "Read model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Load the .ms model.
|
||||
auto model = mindspore::lite::Model::Import(model_buf, size);
|
||||
delete[](model_buf);
|
||||
if (model == nullptr) {
|
||||
std::cerr << "Import model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Compile MindSpore Lite model.
|
||||
auto session1 = CreateSessionAndCompileByModel(model);
|
||||
if (session1 == nullptr) {
|
||||
delete model;
|
||||
std::cerr << "Create session failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Compile MindSpore Lite model.
|
||||
auto session2 = CreateSessionAndCompileByModel(model);
|
||||
if (session2 == nullptr) {
|
||||
delete model;
|
||||
std::cerr << "Create session failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Note: when use model->Free(), the model can not be compiled again.
|
||||
model->Free();
|
||||
|
||||
std::thread thread1([&]() {
|
||||
GetInputsByTensorNameAndSetData(session1);
|
||||
auto status = session1->RunGraph();
|
||||
if (status != 0) {
|
||||
if (model != nullptr) {
|
||||
delete model;
|
||||
model = nullptr;
|
||||
}
|
||||
std::cerr << "Inference error " << status << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "Session1 inference success" << std::endl;
|
||||
});
|
||||
|
||||
std::thread thread2([&]() {
|
||||
GetInputsByTensorNameAndSetData(session2);
|
||||
auto status = session2->RunGraph();
|
||||
if (status != 0) {
|
||||
if (model != nullptr) {
|
||||
delete model;
|
||||
model = nullptr;
|
||||
}
|
||||
std::cerr << "Inference error " << status << std::endl;
|
||||
return;
|
||||
}
|
||||
std::cout << "Session2 inference success" << std::endl;
|
||||
});
|
||||
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
|
||||
// Get outputs data.
|
||||
// You can also get output through other methods,
|
||||
// and you can refer to GetOutputByTensorName() or GetOutputs().
|
||||
GetOutputsByNodeName(session1);
|
||||
GetOutputsByNodeName(session2);
|
||||
|
||||
// Delete model buffer.
|
||||
if (model != nullptr) {
|
||||
delete model;
|
||||
model = nullptr;
|
||||
}
|
||||
// Delete session buffer.
|
||||
delete session1;
|
||||
delete session2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RunWithSharedMemoryPool(const char *model_path) {
|
||||
size_t size = 0;
|
||||
char *model_buf = ReadFile(model_path, &size);
|
||||
if (model_buf == nullptr) {
|
||||
std::cerr << "Read model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
auto model = mindspore::lite::Model::Import(model_buf, size);
|
||||
delete[](model_buf);
|
||||
if (model == nullptr) {
|
||||
std::cerr << "Import model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto context1 = std::make_shared<mindspore::lite::Context>();
|
||||
if (context1 == nullptr) {
|
||||
delete model;
|
||||
std::cerr << "New context failed while running." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
auto session1 = mindspore::session::LiteSession::CreateSession(context1.get());
|
||||
|
||||
if (session1 == nullptr) {
|
||||
delete model;
|
||||
std::cerr << "CreateSession failed while running." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
auto ret = session1->CompileGraph(model);
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
delete model;
|
||||
std::cerr << "Compile failed while running." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto context2 = std::make_shared<mindspore::lite::Context>();
|
||||
if (context2 == nullptr) {
|
||||
delete model;
|
||||
std::cerr << "New context failed while running." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Use the same allocator to share the memory pool.
|
||||
context2->allocator = context1->allocator;
|
||||
|
||||
auto session2 = mindspore::session::LiteSession::CreateSession(context2.get());
|
||||
if (session2 == nullptr) {
|
||||
delete model;
|
||||
std::cerr << "CreateSession failed while running " << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = session2->CompileGraph(model);
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
delete model;
|
||||
std::cerr << "Compile failed while running " << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Note: when use model->Free(), the model can not be compiled again.
|
||||
model->Free();
|
||||
|
||||
// Set inputs data.
|
||||
// You can also get input through other methods, and you can refer to GetInputsAndSetData()
|
||||
GetInputsByTensorNameAndSetData(session1);
|
||||
GetInputsByTensorNameAndSetData(session2);
|
||||
|
||||
ret = session1->RunGraph();
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
std::cerr << "Inference error " << ret << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = session2->RunGraph();
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
delete model;
|
||||
std::cerr << "Inference error " << ret << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get outputs data.
|
||||
// You can also get output through other methods,
|
||||
// and you can refer to GetOutputByTensorName() or GetOutputs().
|
||||
GetOutputsByNodeName(session1);
|
||||
GetOutputsByNodeName(session2);
|
||||
|
||||
// Delete model buffer.
|
||||
delete model;
|
||||
// Delete session buffer.
|
||||
delete session1;
|
||||
delete session2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RunCallback(const char *model_path) {
|
||||
size_t size = 0;
|
||||
char *model_buf = ReadFile(model_path, &size);
|
||||
if (model_buf == nullptr) {
|
||||
std::cerr << "Read model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Load the .ms model.
|
||||
auto model = mindspore::lite::Model::Import(model_buf, size);
|
||||
delete[](model_buf);
|
||||
if (model == nullptr) {
|
||||
std::cerr << "Import model file failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
// Compile MindSpore Lite model.
|
||||
auto session = CreateSessionAndCompileByModel(model);
|
||||
if (session == nullptr) {
|
||||
delete model;
|
||||
std::cerr << "Create session failed." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Note: when use model->Free(), the model can not be compiled again.
|
||||
model->Free();
|
||||
|
||||
// Set inputs data.
|
||||
// You can also get input through other methods, and you can refer to GetInputsAndSetData()
|
||||
GetInputsByTensorNameAndSetData(session);
|
||||
|
||||
// Definition of callback function before forwarding operator.
|
||||
auto before_call_back = [&](const std::vector<mindspore::tensor::MSTensor *> &before_inputs,
|
||||
const std::vector<mindspore::tensor::MSTensor *> &before_outputs,
|
||||
const mindspore::CallBackParam &call_param) {
|
||||
std::cout << "Before forwarding " << call_param.node_name << " " << call_param.node_type << std::endl;
|
||||
return true;
|
||||
};
|
||||
// Definition of callback function after forwarding operator.
|
||||
auto after_call_back = [&](const std::vector<mindspore::tensor::MSTensor *> &after_inputs,
|
||||
const std::vector<mindspore::tensor::MSTensor *> &after_outputs,
|
||||
const mindspore::CallBackParam &call_param) {
|
||||
std::cout << "After forwarding " << call_param.node_name << " " << call_param.node_type << std::endl;
|
||||
return true;
|
||||
};
|
||||
|
||||
session->BindThread(true);
|
||||
auto ret = session->RunGraph(before_call_back, after_call_back);
|
||||
if (ret != mindspore::lite::RET_OK) {
|
||||
delete model;
|
||||
std::cerr << "Inference error " << ret << std::endl;
|
||||
return ret;
|
||||
}
|
||||
session->BindThread(false);
|
||||
|
||||
// Get outputs data.
|
||||
// You can also get output through other methods,
|
||||
// and you can refer to GetOutputByTensorName() or GetOutputs().
|
||||
GetOutputsByNodeName(session);
|
||||
|
||||
// Delete model buffer.
|
||||
delete model;
|
||||
// Delete session buffer.
|
||||
delete session;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
if (argc < 3) {
|
||||
std::cerr << "Usage: ./runtime_cpp model_path flag" << std::endl;
|
||||
std::cerr << "Example: ./runtime_cpp ../model/mobilenetv2.ms 0" << std::endl;
|
||||
std::cerr << "When your Flag is 0, you will run MindSpore Lite inference." << std::endl;
|
||||
std::cerr << "When your Flag is 1, you will run MindSpore Lite inference with resize." << std::endl;
|
||||
std::cerr << "When your Flag is 2, you will run MindSpore Lite inference with CreateSession simplified API."
|
||||
<< std::endl;
|
||||
std::cerr << "When your Flag is 3, you will run MindSpore Lite inference with session parallel." << std::endl;
|
||||
std::cerr << "When your Flag is 4, you will run MindSpore Lite inference with shared memory pool." << std::endl;
|
||||
std::cerr << "When your Flag is 5, you will run MindSpore Lite inference with callback." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::string version = mindspore::lite::Version();
|
||||
std::cout << "MindSpore Lite Version is " << version << std::endl;
|
||||
auto model_path = argv[1];
|
||||
auto flag = argv[2];
|
||||
if (strcmp(flag, "0") == 0) {
|
||||
return Run(model_path);
|
||||
} else if (strcmp(flag, "1") == 0) {
|
||||
return RunResize(model_path);
|
||||
} else if (strcmp(flag, "2") == 0) {
|
||||
return RunCreateSessionSimplified(model_path);
|
||||
} else if (strcmp(flag, "3") == 0) {
|
||||
return RunSessionParallel(model_path);
|
||||
} else if (strcmp(flag, "4") == 0) {
|
||||
return RunWithSharedMemoryPool(model_path);
|
||||
} else if (strcmp(flag, "5") == 0) {
|
||||
return RunCallback(model_path);
|
||||
} else {
|
||||
std::cerr << "Unsupported Flag " << flag << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue