forked from mindspore-Ecosystem/mindspore
add cropper
This commit is contained in:
parent
f40a4781e4
commit
92c1822942
|
@ -55,7 +55,7 @@ if (BUILD_MINDDATA STREQUAL "lite")
|
|||
endif ()
|
||||
|
||||
if (BUILD_MINDDATA STREQUAL "lite_cv")
|
||||
if (PLATFORM_ARM64)
|
||||
if (PLATFORM_ARM64)
|
||||
install(DIRECTORY ${TOP_DIR}/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv DESTINATION ${MIND_DATA_INC_DIR} COMPONENT ${COMPONENT_NAME} FILES_MATCHING PATTERN "*.h")
|
||||
install(FILES ${TOP_DIR}/mindspore/lite/build/minddata/libminddata-lite.so DESTINATION ${MIND_DATA_LIB_DIR} COMPONENT ${COMPONENT_NAME})
|
||||
elseif (PLATFORM_ARM32)
|
||||
|
@ -81,7 +81,7 @@ if (PLATFORM_ARM64)
|
|||
install(DIRECTORY ${flatbuffers_INC} DESTINATION ${FLATBF_DIR} COMPONENT ${COMPONENT_NAME})
|
||||
if (ENABLE_TOOLS)
|
||||
install(TARGETS benchmark RUNTIME DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/benchmark COMPONENT ${COMPONENT_NAME})
|
||||
endif()
|
||||
endif ()
|
||||
elseif (PLATFORM_ARM32)
|
||||
if (SUPPORT_TRAIN)
|
||||
install(DIRECTORY ${TOP_DIR}/mindspore/lite/include/ DESTINATION ${INC_DIR} COMPONENT ${COMPONENT_NAME} FILES_MATCHING PATTERN "*.h")
|
||||
|
@ -96,7 +96,7 @@ elseif (PLATFORM_ARM32)
|
|||
install(DIRECTORY ${flatbuffers_INC} DESTINATION ${FLATBF_DIR} COMPONENT ${COMPONENT_NAME})
|
||||
if (ENABLE_TOOLS)
|
||||
install(TARGETS benchmark RUNTIME DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/benchmark COMPONENT ${COMPONENT_NAME})
|
||||
endif()
|
||||
endif ()
|
||||
elseif (WIN32)
|
||||
get_filename_component(CXX_DIR ${CMAKE_CXX_COMPILER} PATH)
|
||||
file(GLOB LIB_LIST ${CXX_DIR}/libstdc++-6.dll ${CXX_DIR}/libwinpthread-1.dll ${CXX_DIR}/libssp-0.dll ${CXX_DIR}/libgcc_s_seh-1.dll)
|
||||
|
@ -104,7 +104,7 @@ elseif (WIN32)
|
|||
install(TARGETS converter_lite RUNTIME DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/converter COMPONENT ${COMPONENT_NAME})
|
||||
install(FILES ${LIB_LIST} DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/converter COMPONENT ${COMPONENT_NAME})
|
||||
install(FILES ${TOP_DIR}/build/mindspore/tools/converter/mindspore_core/gvar/libmindspore_gvar.dll DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/converter COMPONENT ${COMPONENT_NAME})
|
||||
install(FILES ${glog_LIBPATH}/../bin/libglog.dll DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/converter COMPONENT ${COMPONENT_NAME})
|
||||
install(FILES ${glog_LIBPATH}/../bin/libglog.dll DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/converter COMPONENT ${COMPONENT_NAME})
|
||||
endif ()
|
||||
if (ENABLE_TOOLS)
|
||||
install(TARGETS benchmark RUNTIME DESTINATION ${MAIN_DIR}-${WIN_RUN_X86_NAME}/benchmark COMPONENT ${WIN_RUN_X86_NAME})
|
||||
|
@ -123,7 +123,7 @@ elseif (WIN32)
|
|||
install(FILES ${TOP_DIR}/build/mindspore/src/libmindspore-lite.a DESTINATION ${WIN_LIB_DIR_RUN_X86} COMPONENT ${WIN_RUN_X86_NAME})
|
||||
install(FILES ${TOP_DIR}/build/mindspore/src/libmindspore-lite.dll.a DESTINATION ${WIN_LIB_DIR_RUN_X86} COMPONENT ${WIN_RUN_X86_NAME})
|
||||
install(FILES ${TOP_DIR}/build/mindspore/src/libmindspore-lite.dll DESTINATION ${WIN_LIB_DIR_RUN_X86} COMPONENT ${WIN_RUN_X86_NAME})
|
||||
endif()
|
||||
endif ()
|
||||
else ()
|
||||
if (SUPPORT_TRAIN)
|
||||
install(DIRECTORY ${TOP_DIR}/mindspore/lite/include/ DESTINATION ${INC_DIR_RUN_X86} COMPONENT ${RUN_X86_COMPONENT_NAME} FILES_MATCHING PATTERN "*.h")
|
||||
|
@ -140,10 +140,12 @@ else ()
|
|||
install(TARGETS converter_lite RUNTIME DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/converter COMPONENT ${COMPONENT_NAME})
|
||||
install(FILES ${TOP_DIR}/mindspore/lite/build/tools/converter/mindspore_core/gvar/libmindspore_gvar.so DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/lib COMPONENT ${COMPONENT_NAME})
|
||||
install(FILES ${glog_LIBPATH}/libglog.so.0.4.0 DESTINATION ${MAIN_DIR}-${COMPONENT_NAME}/third_party/glog/lib RENAME libglog.so.0 COMPONENT ${COMPONENT_NAME})
|
||||
endif()
|
||||
endif ()
|
||||
if (ENABLE_TOOLS)
|
||||
install(TARGETS benchmark RUNTIME DESTINATION ${MAIN_DIR}-${RUN_X86_COMPONENT_NAME}/benchmark COMPONENT ${RUN_X86_COMPONENT_NAME})
|
||||
endif()
|
||||
install(TARGETS lib_cropper RUNTIME DESTINATION ${MAIN_DIR}-${RUN_X86_COMPONENT_NAME}/lib_cropper COMPONENT ${RUN_X86_COMPONENT_NAME})
|
||||
install(FILES ${TOP_DIR}/mindspore/lite/build/tools/lib_cropper/cropper_mapping_cpu.cfg DESTINATION ${MAIN_DIR}-${RUN_X86_COMPONENT_NAME}/lib_cropper COMPONENT ${RUN_X86_COMPONENT_NAME})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
|
@ -164,6 +166,6 @@ if (WIN32)
|
|||
set(CPACK_PACKAGE_DIRECTORY ${TOP_DIR}/output)
|
||||
else ()
|
||||
set(CPACK_PACKAGE_DIRECTORY ${TOP_DIR}/output/tmp)
|
||||
endif()
|
||||
endif ()
|
||||
set(CPACK_PACKAGE_CHECKSUM SHA256)
|
||||
include(CPack)
|
||||
|
|
|
@ -224,6 +224,7 @@ if (NOT WIN32)
|
|||
if (ENABLE_TOOLS)
|
||||
if (NOT PLATFORM_ARM32 AND NOT PLATFORM_ARM64)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/schema_gen)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/lib_cropper)
|
||||
endif ()
|
||||
endif()
|
||||
if (BUILD_TESTCASES)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# add shared link library
|
||||
set(COMMON_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../common/flag_parser.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/common/file_utils.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../src/common/utils.cc
|
||||
)
|
||||
|
||||
add_executable(lib_cropper
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lib_cropper.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cropper_flags.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cropper_utils.cc
|
||||
${COMMON_SRC})
|
||||
|
||||
add_dependencies(lib_cropper fbs_src)
|
||||
|
||||
target_link_libraries(lib_cropper mindspore-lite_static)
|
||||
|
||||
add_custom_command(TARGET lib_cropper POST_BUILD COMMAND
|
||||
bash build_cropper_config.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
|
@ -0,0 +1,170 @@
|
|||
#!/bin/bash
|
||||
|
||||
CURRENT_PATH=$(pwd)
|
||||
MINDSPORE_HOME="${CURRENT_PATH}/../../../.."
|
||||
echo "MINDSPORE_HOME path is ${MINDSPORE_HOME}"
|
||||
CROPPER_OUTPUT_DIR=${MINDSPORE_HOME}/mindspore/lite/build/tools/lib_cropper
|
||||
mkdir -p ${CROPPER_OUTPUT_DIR}
|
||||
MAPPING_OUTPUT_FILE_NAME_TMP=${CROPPER_OUTPUT_DIR}/cropper_mapping_cpu_tmp.cfg
|
||||
MAPPING_OUTPUT_FILE_NAME=${CROPPER_OUTPUT_DIR}/cropper_mapping_cpu.cfg
|
||||
echo "MAPPING_OUTPUT_FILE_NAME is ${MAPPING_OUTPUT_FILE_NAME}"
|
||||
[ -n "${MAPPING_OUTPUT_FILE_NAME_TMP}" ] && rm -f ${MAPPING_OUTPUT_FILE_NAME_TMP}
|
||||
[ -n "${MAPPING_OUTPUT_FILE_NAME}" ] && rm -f ${MAPPING_OUTPUT_FILE_NAME}
|
||||
ops_list=()
|
||||
DEFINE_STR="-DENABLE_ANDROID -DENABLE_ARM -DENABLE_ARM64 -DENABLE_NEON -DNO_DLIB -DUSE_ANDROID_LOG -DANDROID"
|
||||
# get the flatbuffers path
|
||||
if [ ${MSLIBS_CACHE_PATH} ]; then
|
||||
FLATBUFFERS_LIST=($(ls -d ${MSLIBS_CACHE_PATH}/flatbuffers_*/include))
|
||||
FLATBUFFERS=${FLATBUFFERS_LIST[0]}
|
||||
echo "FLATBUFFERS path is ${FLATBUFFERS}"
|
||||
else
|
||||
FLATBUFFERS=$(ls -d ${MINDSPORE_HOME}/mindspore/lite/build/.mslib/flatbuffers_*/include)
|
||||
echo "FLATBUFFERS path is ${FLATBUFFERS}"
|
||||
fi
|
||||
|
||||
HEADER_LOCATION="-I${MINDSPORE_HOME}
|
||||
-I${MINDSPORE_HOME}/mindspore/core
|
||||
-I${MINDSPORE_HOME}/mindspore/core/ir
|
||||
-I${MINDSPORE_HOME}/mindspore/ccsrc
|
||||
-I${MINDSPORE_HOME}/mindspore/lite
|
||||
-I${MINDSPORE_HOME}/mindspore/lite/src/runtime/kernel/arm
|
||||
-I${MINDSPORE_HOME}/third_party
|
||||
-I${MINDSPORE_HOME}/mindspore/lite/build
|
||||
-I${MINDSPORE_HOME}/cmake/../third_party/securec/include
|
||||
-I${FLATBUFFERS}
|
||||
-I${MINDSPORE_HOME}/mindspore/lite/build/schema
|
||||
-I${MINDSPORE_HOME}/mindspore/lite/build/schema/inner
|
||||
-I${MINDSPORE_HOME}/mindspore/lite/src/../nnacl
|
||||
-I${MINDSPORE_HOME}/mindspore/lite/src/../nnacl/optimize"
|
||||
|
||||
REMOVE_LISTS_STR=""
|
||||
getDeep() {
|
||||
map_files=$(gcc -MM ${2} ${DEFINE_STR} ${HEADER_LOCATION})
|
||||
# first is *.o second is *.cc
|
||||
array_deep=($(echo ${map_files} | awk -F '\' '{for(i=3;i<=NF;i++){print $i}}' | grep -E 'src/runtime|nnacl' | egrep -v ${REMOVE_LISTS_STR}))
|
||||
for array_deep_file in ${array_deep[@]}; do
|
||||
# only add existing files
|
||||
if [[ -e ${array_deep_file%h*}cc ]]; then
|
||||
file_split=$(echo ${array_deep_file} | awk -F '/' '{print $NF}')
|
||||
echo "${1},${3},${file_split%h*}cc.o" >>${MAPPING_OUTPUT_FILE_NAME_TMP}
|
||||
fi
|
||||
if [[ -e ${array_deep_file%h*}c ]]; then
|
||||
file_split=$(echo ${array_deep_file} | awk -F '/' '{print $NF}')
|
||||
echo "${1},${3},${file_split%h*}c.o" >>${MAPPING_OUTPUT_FILE_NAME_TMP}
|
||||
fi
|
||||
done
|
||||
}
|
||||
getOpsFile() {
|
||||
echo "start get operator mapping file $3"
|
||||
for type in ${ops_list[@]}; do
|
||||
# get mapping
|
||||
ret=$(egrep -r -l "$1${type}," $2)
|
||||
array=(${ret})
|
||||
for file in ${array[@]}; do
|
||||
# delete \n
|
||||
out_file=$(echo ${file} | awk -F '/' '{print $NF}')
|
||||
# concat schemaType + fileType + fileName append to files
|
||||
echo "${type},${3},${out_file}.o" >>${MAPPING_OUTPUT_FILE_NAME_TMP}
|
||||
map_files=$(gcc -MM ${file} ${DEFINE_STR} ${HEADER_LOCATION})
|
||||
# first is *.o second is *.cc
|
||||
array_file=($(echo ${map_files} | awk -F '\' '{for(i=3;i<=NF;i++){print $i}}' | grep -E 'src/runtime|nnacl' | egrep -v ${REMOVE_LISTS_STR}))
|
||||
for array_file in ${array_file[@]}; do
|
||||
# only add existing files
|
||||
if [[ -e ${array_file%h*}cc ]]; then
|
||||
getDeep ${type} ${array_file%h*}cc ${3} &
|
||||
array_file_split=$(echo ${array_file} | awk -F '/' '{print $NF}')
|
||||
echo "${type},${3},${array_file_split%h*}cc.o" >>${MAPPING_OUTPUT_FILE_NAME_TMP}
|
||||
fi
|
||||
if [[ -e ${array_file%h*}c ]]; then
|
||||
getDeep ${type} ${array_file%h*}c ${3} &
|
||||
array_file_split=$(echo ${array_file} | awk -F '/' '{print $NF}')
|
||||
echo "${type},${3},${array_file_split%h*}c.o" >>${MAPPING_OUTPUT_FILE_NAME_TMP}
|
||||
fi
|
||||
done
|
||||
done
|
||||
done
|
||||
}
|
||||
getCommonFile() {
|
||||
echo "start get common files"
|
||||
include_h=($(ls ${MINDSPORE_HOME}/mindspore/lite/include/*.h))
|
||||
src_files_h=($(ls ${MINDSPORE_HOME}/mindspore/lite/src/*.h))
|
||||
common_files_h=($(ls ${MINDSPORE_HOME}/mindspore/lite/src/common/*.h))
|
||||
runtime_files_h=($(ls ${MINDSPORE_HOME}/mindspore/lite/src/runtime/*.h))
|
||||
others_files=(
|
||||
${MINDSPORE_HOME}/mindspore/lite/src/populate/populate_register.h
|
||||
${MINDSPORE_HOME}/mindspore/lite/src/ops/primitive_c.h
|
||||
${MINDSPORE_HOME}/mindspore/lite/nnacl/nnacl_utils.h
|
||||
${MINDSPORE_HOME}/mindspore/lite/nnacl/pack.h
|
||||
${MINDSPORE_HOME}/mindspore/lite/src/runtime/kernel/arm/fp16/common_fp16.h
|
||||
)
|
||||
all_files_h=(${include_h[@]} ${src_files_h[@]} ${common_files_h[@]} ${runtime_files_h[@]} ${others_files[@]})
|
||||
|
||||
# concat regx
|
||||
REMOVE_LISTS_STR="${all_files_h[0]}"
|
||||
for val in ${all_files_h[@]:1}; do
|
||||
REMOVE_LISTS_STR="$REMOVE_LISTS_STR|$val"
|
||||
done
|
||||
|
||||
src_files=($(ls ${MINDSPORE_HOME}/mindspore/lite/src/*.cc))
|
||||
common_files=($(ls ${MINDSPORE_HOME}/mindspore/lite/src/common/*.cc))
|
||||
runtime_files_cc=($(ls ${MINDSPORE_HOME}/mindspore/lite/src/runtime/*.cc))
|
||||
runtime_files_c=($(ls ${MINDSPORE_HOME}/mindspore/lite/src/runtime/*.c))
|
||||
|
||||
# sava all assembly files
|
||||
assembly_files=("$(ls ${MINDSPORE_HOME}/mindspore/lite/nnacl/assembly/*/*.S)")
|
||||
others_files=(
|
||||
${MINDSPORE_HOME}/mindspore/lite/src/ops/primitive_c.cc
|
||||
${MINDSPORE_HOME}/mindspore/lite/nnacl/nnacl_utils.c
|
||||
${MINDSPORE_HOME}/mindspore/lite/nnacl/pack.c
|
||||
${MINDSPORE_HOME}/mindspore/lite/src/runtime/kernel/arm/fp16/common_fp16.cc
|
||||
${MINDSPORE_HOME}/mindspore/lite/src/ops/populate/arithmetic_populate.cc
|
||||
${MINDSPORE_HOME}/mindspore/lite/src/ops/populate/arithmetic_self_populate.cc
|
||||
)
|
||||
all_files=(${src_files[@]} ${common_files[@]} ${runtime_files_cc[@]} ${runtime_files_c[@]} ${others_files[@]} ${assembly_files[@]})
|
||||
|
||||
for file in ${all_files[@]}; do
|
||||
map_files=$(gcc -MM ${file} ${DEFINE_STR} ${HEADER_LOCATION})
|
||||
# first is *.o second is *.cc
|
||||
array_runtime=($(echo ${map_files} | awk -F '\' '{for(i=3;i<=NF;i++){print $i}}' | grep -v "flatbuffers" | egrep -v ${REMOVE_LISTS_STR}))
|
||||
# only add existing files
|
||||
for array_runtime_file in "${array_runtime[@]}"; do
|
||||
if [[ -e ${array_runtime_file%h*}cc && ! ${all_files[*]} =~ ${array_runtime_file%h*}cc ]]; then
|
||||
all_files=("${all_files[@]}" "${array_runtime_file%h*}cc")
|
||||
fi
|
||||
if [[ -e ${array_runtime_file%h*}c && ! ${all_files[*]} =~ ${array_runtime_file%h*}c ]]; then
|
||||
all_files=("${all_files[@]}" "${array_runtime_file%h*}c")
|
||||
fi
|
||||
done
|
||||
done
|
||||
for file in ${all_files[@]}; do
|
||||
file=$(echo ${file} | awk -F '/' '{print $NF}')
|
||||
echo "CommonFile,common,${file}.o" >>${MAPPING_OUTPUT_FILE_NAME_TMP} &
|
||||
done
|
||||
wait
|
||||
}
|
||||
|
||||
# automatically generate operator list
|
||||
generateOpsList() {
|
||||
echo "start generate operator list"
|
||||
ops=($(egrep "PrimitiveType_.* = " "${MINDSPORE_HOME}/mindspore/lite/build/schema/model_generated.h" | awk -F '_' '{print $2}' | awk -F ' ' '{print $1}'))
|
||||
|
||||
ops_num=$((${#ops[@]} - 3))
|
||||
echo "ops nums:${ops_num}"
|
||||
ops_list=${ops[@]:1:$ops_num}
|
||||
}
|
||||
echo "Start getting all file associations."
|
||||
generateOpsList
|
||||
getCommonFile
|
||||
# get src/ops
|
||||
getOpsFile "Registry\(schema::PrimitiveType_" "${MINDSPORE_HOME}/mindspore/lite/src/ops" "prototype" &
|
||||
getOpsFile "REG_KERNEL\(.*?, kNumberTypeFloat32, PrimitiveType_" "${MINDSPORE_HOME}/mindspore/lite/src/runtime/kernel/arm" "kNumberTypeFloat32" &
|
||||
getOpsFile "REG_KERNEL\(.*?, kNumberTypeFloat16, PrimitiveType_" "${MINDSPORE_HOME}/mindspore/lite/src/runtime/kernel/arm" "kNumberTypeFloat16" &
|
||||
getOpsFile "REG_KERNEL\(.*?, kNumberTypeInt8, PrimitiveType_" "${MINDSPORE_HOME}/mindspore/lite/src/runtime/kernel/arm" "kNumberTypeInt8" &
|
||||
wait
|
||||
echo "remove duplicate files"
|
||||
# remove duplicate files
|
||||
sort ${MAPPING_OUTPUT_FILE_NAME_TMP} | uniq >${MAPPING_OUTPUT_FILE_NAME}
|
||||
# modify file permissions to read-only
|
||||
[ -n "${MAPPING_OUTPUT_FILE_NAME_TMP}" ] && rm -f ${MAPPING_OUTPUT_FILE_NAME_TMP}
|
||||
chmod 444 ${MAPPING_OUTPUT_FILE_NAME}
|
||||
echo "Complete all tasks."
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* Copyright 2020 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 "tools/lib_cropper/cropper_flags.h"
|
||||
#include <string>
|
||||
#include "tools/lib_cropper/cropper_utils.h"
|
||||
#include "src/common/file_utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
namespace cropper {
|
||||
CropperFlags::CropperFlags() {
|
||||
AddFlag(&CropperFlags::package_file_, "packageFile", "The libmindspore-lite.a file that needs to be cropped", "");
|
||||
AddFlag(&CropperFlags::model_file_, "modelFile", "List of model files, separated by commas", "");
|
||||
AddFlag(&CropperFlags::model_folder_path_, "modelFolderPath", "Load all ms models in the folder", "");
|
||||
AddFlag(&CropperFlags::config_file_, "configFile", "The mapping configuration file path", "");
|
||||
AddFlag(&CropperFlags::output_file_, "outputFile", "Output library file path", "");
|
||||
}
|
||||
|
||||
int CropperFlags::Init(int argc, const char **argv) {
|
||||
if (argc == 1) {
|
||||
std::cout << this->Usage() << std::endl;
|
||||
return RET_SUCCESS_EXIT;
|
||||
}
|
||||
Option<std::string> err = this->ParseFlags(argc, argv);
|
||||
|
||||
if (err.IsSome()) {
|
||||
std::cerr << err.Get();
|
||||
std::cerr << this->Usage() << std::endl;
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
|
||||
if (this->help) {
|
||||
std::cout << this->Usage() << std::endl;
|
||||
return RET_SUCCESS_EXIT;
|
||||
}
|
||||
|
||||
MS_LOG(INFO) << "packageFile = " << this->package_file_;
|
||||
MS_LOG(INFO) << "modelFile = " << this->model_file_;
|
||||
MS_LOG(INFO) << "modelFolderPath = " << this->model_folder_path_;
|
||||
MS_LOG(INFO) << "configFile = " << this->config_file_;
|
||||
MS_LOG(INFO) << "outputFile = " << this->output_file_;
|
||||
|
||||
if (this->package_file_.empty()) {
|
||||
std::cerr << "INPUT MISSING: packageFile is necessary" << std::endl;
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
} else {
|
||||
// Verify whether it is a static library file(.a)
|
||||
if (ValidFileSuffix(this->package_file_, "a") != RET_OK) {
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
this->package_file_ = RealPath(this->package_file_.c_str());
|
||||
if (this->package_file_.empty()) {
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->model_file_.empty() && this->model_folder_path_.empty()) {
|
||||
std::cerr << "INPUT MISSING: modelFile or modelFolderPath is necessary" << std::endl;
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
} else if (!this->model_file_.empty() && !this->model_folder_path_.empty()) {
|
||||
std::cerr << "INPUT MISSING: modelFile and modelFolderPath must choose one" << std::endl;
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
} else if (!this->model_folder_path_.empty()) {
|
||||
this->model_folder_path_ = RealPath(this->model_folder_path_.c_str());
|
||||
if (this->model_folder_path_.empty()) {
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->config_file_.empty()) {
|
||||
std::cerr << "INPUT MISSING: configFile is necessary" << std::endl;
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
this->config_file_ = RealPath(this->config_file_.c_str());
|
||||
if (this->config_file_.empty()) {
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
|
||||
if (this->output_file_.empty()) {
|
||||
this->output_file_ = this->package_file_;
|
||||
}
|
||||
this->output_file_ = RealPath(this->output_file_.c_str());
|
||||
if (this->output_file_.empty()) {
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
} // namespace cropper
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_LITE_TOOLS_LIB_CROPPER_LIB_CROPPER_FLAGS_H
|
||||
#define MINDSPORE_LITE_TOOLS_LIB_CROPPER_LIB_CROPPER_FLAGS_H
|
||||
|
||||
#include <string>
|
||||
#include "tools/common/flag_parser.h"
|
||||
#include "ir/dtype/type_id.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
namespace cropper {
|
||||
|
||||
class CropperFlags : public virtual mindspore::lite::FlagParser {
|
||||
public:
|
||||
CropperFlags();
|
||||
~CropperFlags() override = default;
|
||||
int Init(int argc, const char **argv);
|
||||
|
||||
public:
|
||||
std::string package_file_;
|
||||
std::string model_file_;
|
||||
std::string model_folder_path_;
|
||||
std::string config_file_;
|
||||
std::string output_file_;
|
||||
};
|
||||
} // namespace cropper
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
||||
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Copyright 2020 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 "tools/lib_cropper/cropper_utils.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "src/common/log_adapter.h"
|
||||
#include "include/errorcode.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
namespace cropper {
|
||||
int ValidFileSuffix(const std::string &filename, const std::string &suffix) {
|
||||
std::string suffixStr = filename.substr(filename.find_last_of('.') + 1);
|
||||
if (suffix == suffixStr) {
|
||||
return RET_OK;
|
||||
} else {
|
||||
MS_LOG(ERROR) << "The file name suffix needs: " << suffix << ", but file is " << filename;
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
int ValidFile(std::ifstream &in_file, const char *file_path) {
|
||||
if (!in_file.good()) {
|
||||
std::cerr << "file: " << file_path << " is not exist" << std::endl;
|
||||
MS_LOG(ERROR) << "file: " << file_path << " is not exist";
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
if (!in_file.is_open()) {
|
||||
std::cerr << "file: " << file_path << " open failed" << std::endl;
|
||||
MS_LOG(ERROR) << "file: " << file_path << " open failed";
|
||||
in_file.close();
|
||||
return RET_ERROR;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
} // namespace cropper
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_LITE_TOOLS_LIB_CROPPER_LIB_CROPPER_UTILS_H
|
||||
#define MINDSPORE_LITE_TOOLS_LIB_CROPPER_LIB_CROPPER_UTILS_H
|
||||
#include <string>
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
namespace cropper {
|
||||
int ValidFileSuffix(const std::string &filename, const std::string &suffix);
|
||||
int ValidFile(std::ifstream &in_file, const char *file_path);
|
||||
} // namespace cropper
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
||||
#endif // MINDSPORE_LITE_TOOLS_CROPPER_CROPPER_UTILS_H
|
|
@ -0,0 +1,276 @@
|
|||
/**
|
||||
* Copyright 2020 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 <memory>
|
||||
#include <string>
|
||||
#include "tools/lib_cropper/lib_cropper.h"
|
||||
#include "tools/lib_cropper/cropper_utils.h"
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
namespace cropper {
|
||||
static const char *DELIM_COMMA = ",";
|
||||
|
||||
int Cropper::ReadPackage() {
|
||||
std::ifstream in_file(this->flags_->package_file_);
|
||||
if (ValidFile(in_file, this->flags_->package_file_.c_str()) == RET_OK) {
|
||||
in_file.close();
|
||||
|
||||
char buf[BUF_SIZE];
|
||||
String cmd = "ar -t " + this->flags_->package_file_;
|
||||
MS_LOG(DEBUG) << cmd;
|
||||
|
||||
FILE *p_file = popen(cmd.c_str(), "r");
|
||||
if (!p_file) {
|
||||
MS_LOG(ERROR) << "Error to popen" << this->flags_->package_file_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
while (fgets(buf, BUF_SIZE, p_file) != nullptr) {
|
||||
this->all_files_.push_back(String(buf).substr(0, String(buf).length() - 1));
|
||||
this->discard_files_.push_back(String(buf).substr(0, String(buf).length() - 1));
|
||||
}
|
||||
pclose(p_file);
|
||||
MS_LOG(DEBUG) << "file nums: " << this->all_files_.size();
|
||||
} else {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int Cropper::RunCropper() {
|
||||
int status;
|
||||
status = ReadPackage();
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "read package failed.";
|
||||
return status;
|
||||
}
|
||||
status = GetModelFiles();
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "get model files failed.";
|
||||
return status;
|
||||
}
|
||||
status = GetModelOps();
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "get model ops failed.";
|
||||
return status;
|
||||
}
|
||||
status = GetOpMatchFiles();
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "get op match files failed.";
|
||||
return status;
|
||||
}
|
||||
status = GetDiscardFileList();
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "get discard file list failed.";
|
||||
return status;
|
||||
}
|
||||
status = CutPackage();
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "cut package failed.";
|
||||
return status;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
int Cropper::GetModelOps() {
|
||||
for (const auto &path : this->model_files_) {
|
||||
auto context = std::make_shared<Context>();
|
||||
size_t buffer_lens;
|
||||
char *graph_buf = ReadFile(path.c_str(), &buffer_lens);
|
||||
if (graph_buf == nullptr) {
|
||||
MS_LOG(ERROR) << "Read model file failed while running " << path.c_str();
|
||||
std::cerr << "Read model file failed while running " << path.c_str() << std::endl;
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto meta_graph = schema::GetMetaGraph(graph_buf);
|
||||
if (meta_graph == nullptr) {
|
||||
delete[] graph_buf;
|
||||
MS_LOG(ERROR) << "meta_graph is nullptr!";
|
||||
std::cerr << "meta_graph is nullptr!" << std::endl;
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto nodes = meta_graph->nodes();
|
||||
for (auto node : *nodes) {
|
||||
this->all_operators_.insert(node->primitive()->value_type());
|
||||
MS_LOG(DEBUG) << "PrimitiveType:" << schema::EnumNamePrimitiveType(node->primitive()->value_type())
|
||||
<< " QuantType:" << schema::EnumNameQuantType(node->quantType());
|
||||
// QuantType_AwareTraining may change
|
||||
if (node->quantType() == schema::QuantType_AwareTraining || node->quantType() == schema::QuantType_PostTraining) {
|
||||
this->int8_operators_.insert(node->primitive()->value_type());
|
||||
} else {
|
||||
this->fp32_operators_.insert(node->primitive()->value_type());
|
||||
}
|
||||
}
|
||||
delete[] graph_buf;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
int Cropper::GetModelFiles() {
|
||||
if (!this->flags_->model_file_.empty()) {
|
||||
auto files = StringSplit(this->flags_->model_file_, std::string(DELIM_COMMA));
|
||||
for (const auto &file : files) {
|
||||
if (ValidFileSuffix(file, "ms") != RET_OK) {
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
MS_LOG(DEBUG) << file;
|
||||
String realPath = RealPath(file.c_str());
|
||||
if (realPath.empty()) {
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
this->model_files_.push_back(realPath);
|
||||
}
|
||||
}
|
||||
// get models from folder
|
||||
if (!this->flags_->model_folder_path_.empty()) {
|
||||
String cmd = "ls " + this->flags_->model_folder_path_ + "/*.ms";
|
||||
MS_LOG(DEBUG) << cmd;
|
||||
|
||||
char buf[BUF_SIZE];
|
||||
FILE *p_file = popen(cmd.c_str(), "r");
|
||||
if (!p_file) {
|
||||
MS_LOG(ERROR) << "Error to popen";
|
||||
return RET_ERROR;
|
||||
}
|
||||
while (fgets(buf, BUF_SIZE, p_file) != nullptr) {
|
||||
String realPath = RealPath(String(buf).substr(0, String(buf).length() - 1).c_str());
|
||||
if (realPath.empty()) {
|
||||
return RET_INPUT_PARAM_INVALID;
|
||||
}
|
||||
this->model_files_.emplace_back(realPath);
|
||||
}
|
||||
pclose(p_file);
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int Cropper::GetOpMatchFiles() {
|
||||
std::ifstream in_file(this->flags_->config_file_);
|
||||
if (ValidFile(in_file, this->flags_->config_file_.c_str()) == RET_OK) {
|
||||
MS_LOG(DEBUG) << this->flags_->config_file_.c_str();
|
||||
char buf[BUF_SIZE];
|
||||
while (!in_file.eof()) {
|
||||
in_file.getline(buf, BUF_SIZE);
|
||||
auto mapping = StringSplit(buf, DELIM_COMMA);
|
||||
if (!mapping.empty()) {
|
||||
String primitive = mapping[0];
|
||||
String type = mapping[1];
|
||||
String file = mapping[2];
|
||||
if (type == "kNumberTypeFloat32" || type == "kNumberTypeFloat16") {
|
||||
for (auto op : this->fp32_operators_) {
|
||||
if (schema::EnumNamePrimitiveType(op) == primitive) {
|
||||
MS_LOG(DEBUG) << "kNumberTypeFloat32:" << mapping[2];
|
||||
this->archive_files_.insert(mapping[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (type == "kNumberTypeInt8") {
|
||||
for (auto op : this->int8_operators_) {
|
||||
if (schema::EnumNamePrimitiveType(op) == primitive) {
|
||||
MS_LOG(DEBUG) << "int8_operators_:" << mapping[2];
|
||||
this->archive_files_.insert(mapping[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (type == "prototype") {
|
||||
for (auto op : this->all_operators_) {
|
||||
if (schema::EnumNamePrimitiveType(op) == primitive) {
|
||||
MS_LOG(DEBUG) << "prototype:" << mapping[2];
|
||||
this->archive_files_.insert(mapping[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (type == "common") {
|
||||
MS_LOG(DEBUG) << "common:" << mapping[2];
|
||||
this->archive_files_.insert(mapping[2]);
|
||||
} else {
|
||||
MS_LOG(ERROR) << "invalid type symbol:" << type;
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
in_file.close();
|
||||
} else {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
int Cropper::GetDiscardFileList() {
|
||||
// discard_files_=all_files_-archive_files_
|
||||
for (const auto &archive : this->archive_files_) {
|
||||
for (auto it = this->discard_files_.begin(); it != this->discard_files_.end();) {
|
||||
if (*it == archive) {
|
||||
it = this->discard_files_.erase(it);
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
int Cropper::CutPackage() {
|
||||
String copy_bak_cmd = "cp " + this->flags_->package_file_ + " " + this->flags_->package_file_ + ".bak";
|
||||
String ar_cmd = "ar -d " + this->flags_->package_file_ + ".bak ";
|
||||
for (const auto &file : this->discard_files_) {
|
||||
ar_cmd.append(file).append(" ");
|
||||
}
|
||||
String copy_to_output_cmd = "cp " + this->flags_->package_file_ + ".bak " + this->flags_->output_file_ + " && rm " +
|
||||
this->flags_->package_file_ + ".bak";
|
||||
int status;
|
||||
status = system(copy_bak_cmd.c_str());
|
||||
if (status != 0) {
|
||||
MS_LOG(ERROR) << copy_bak_cmd << " executor failed.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
status = system(ar_cmd.c_str());
|
||||
if (status != 0) {
|
||||
MS_LOG(ERROR) << ar_cmd << " executor failed.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
status = system(copy_to_output_cmd.c_str());
|
||||
if (status != 0) {
|
||||
MS_LOG(ERROR) << copy_to_output_cmd << " executor failed.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int RunCropper(int argc, const char **argv) {
|
||||
CropperFlags flags;
|
||||
int status;
|
||||
status = flags.Init(argc, argv);
|
||||
if (status == RET_SUCCESS_EXIT) {
|
||||
return status;
|
||||
}
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "Flags init Error : " << GetErrorInfo(status);
|
||||
std::cerr << "Flags init Error : " << GetErrorInfo(status) << std::endl;
|
||||
return status;
|
||||
}
|
||||
Cropper cropper(&flags);
|
||||
|
||||
status = cropper.RunCropper();
|
||||
if (status == RET_OK) {
|
||||
MS_LOG(INFO) << "CROPPER RESULT SUCCESS:" << status;
|
||||
std::cout << "CROPPER RESULT SUCCESS:" << status << std::endl;
|
||||
} else {
|
||||
MS_LOG(ERROR) << "CROPPER RESULT FAILED:" << status << " " << GetErrorInfo(status);
|
||||
std::cout << "CROPPER RESULT FAILED:" << status << " " << GetErrorInfo(status) << std::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
} // namespace cropper
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_LITE_TOOLS_LIB_CROPPER_LIB_CROPPER_H_
|
||||
#define MINDSPORE_LITE_TOOLS_LIB_CROPPER_LIB_CROPPER_H_
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "include/model.h"
|
||||
#include "tools/common/flag_parser.h"
|
||||
#include "src/common/file_utils.h"
|
||||
#include "src/common/utils.h"
|
||||
#include "include/lite_session.h"
|
||||
#include "tools/lib_cropper/cropper_flags.h"
|
||||
|
||||
namespace mindspore::lite::cropper {
|
||||
|
||||
class MS_API Cropper {
|
||||
public:
|
||||
explicit Cropper(CropperFlags *flags) : flags_(flags) {}
|
||||
|
||||
~Cropper() = default;
|
||||
|
||||
int RunCropper();
|
||||
|
||||
int ReadPackage();
|
||||
|
||||
int GetModelFiles();
|
||||
|
||||
int GetModelOps();
|
||||
|
||||
int GetOpMatchFiles();
|
||||
|
||||
int GetDiscardFileList();
|
||||
|
||||
int CutPackage();
|
||||
|
||||
std::vector<std::string> model_files_;
|
||||
std::vector<std::string> all_files_;
|
||||
std::set<std::string> archive_files_;
|
||||
std::vector<std::string> discard_files_;
|
||||
|
||||
std::set<schema::PrimitiveType> all_operators_;
|
||||
std::set<schema::PrimitiveType> int8_operators_;
|
||||
std::set<schema::PrimitiveType> fp16_operators_;
|
||||
std::set<schema::PrimitiveType> fp32_operators_;
|
||||
|
||||
private:
|
||||
CropperFlags *flags_;
|
||||
};
|
||||
|
||||
int MS_API RunCropper(int argc, const char **argv);
|
||||
} // namespace mindspore::lite::cropper
|
||||
#endif // MINDSPORE_LITE_TOOLS_CROPPER_CROPPER_H_
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Copyright 2020 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 "tools/lib_cropper/lib_cropper.h"
|
||||
#include "include/version.h"
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
MS_LOG(INFO) << mindspore::lite::Version();
|
||||
return mindspore::lite::cropper::RunCropper(argc, argv);
|
||||
}
|
Loading…
Reference in New Issue