| @@ -1,39 +1,45 @@ | |||
| ## define customized find fucntions, print customized error messages | |||
| ## define customized find functions, print customized error messages | |||
| function(find_required_package pkg_name) | |||
| find_package(${pkg_name}) | |||
| if (NOT ${pkg_name}_FOUND) | |||
| message(FATAL_ERROR "Required package ${pkg_name} not found, please install the package and try building mindspore_serving again.") | |||
| if(NOT ${pkg_name}_FOUND) | |||
| message(FATAL_ERROR "Required package ${pkg_name} not found, please install the package and try" | |||
| " building mindspore_serving again.") | |||
| endif() | |||
| endfunction() | |||
| ## find python, quit if the found python is static | |||
| set(Python3_USE_STATIC_LIBS FALSE) | |||
| find_package(Python3 COMPONENTS Interpreter Development) | |||
| if (Python3_FOUND) | |||
| if(Python3_FOUND) | |||
| message("Python3 found, version: ${Python3_VERSION}") | |||
| message("Python3 library path: ${Python3_LIBRARY_DIRS}") | |||
| message("Python3 library path: ${Python3_LIBRARY}") | |||
| message("Python3 interpreter: ${Python3_EXECUTABLE}") | |||
| else() | |||
| elseif(Python3_LIBRARY AND Python3_EXECUTABLE AND | |||
| ${Python3_VERSION} VERSION_GREATER_EQUAL "3.7.0" AND ${Python3_VERSION} VERSION_LESS "3.9.0") | |||
| message(WARNING "Maybe python3 environment is broken.") | |||
| message("Python3 library path: ${Python3_LIBRARY}") | |||
| message("Python3 interpreter: ${Python3_EXECUTABLE}") | |||
| else() | |||
| message(FATAL_ERROR "Python3 not found, please install Python>=3.7.5, and set --enable-shared " | |||
| "if you are building Python locally") | |||
| endif () | |||
| endif() | |||
| ## packages used both on windows and linux | |||
| if (DEFINED ENV{MS_PATCH_PATH}) | |||
| if(DEFINED ENV{MS_PATCH_PATH}) | |||
| find_program(Patch_EXECUTABLE patch PATHS $ENV{MS_PATCH_PATH}) | |||
| set(Patch_FOUND ${Patch_EXECUTABLE}) | |||
| else () | |||
| else() | |||
| find_package(Patch) | |||
| endif () | |||
| if (NOT Patch_FOUND) | |||
| message(FATAL_ERROR "Patch not found, please set environment variable MS_PATCH_PATH to path where Patch is located, " | |||
| "usually found in GIT_PATH/usr/bin on Windows") | |||
| endif () | |||
| endif() | |||
| if(NOT Patch_FOUND) | |||
| message(FATAL_ERROR "Patch not found, please set environment variable MS_PATCH_PATH to path where Patch is located," | |||
| " usually found in GIT_PATH/usr/bin on Windows") | |||
| endif() | |||
| message(PATCH_EXECUTABLE = ${Patch_EXECUTABLE}) | |||
| find_required_package(Threads) | |||
| ## packages used on Linux | |||
| if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") | |||
| if(NOT CMAKE_SYSTEM_NAME MATCHES "Windows") | |||
| find_required_package(OpenSSL) | |||
| endif() | |||
| @@ -1,12 +1,44 @@ | |||
| set(PYTHON_VERSION ${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) | |||
| if(ENABLE_GITEE) | |||
| if(PYTHON_VERSION MATCHES "3.8") | |||
| set(REQ_URL "https://gitee.com/mirrors/pybind11/repository/archive/v2.6.1.tar.gz") | |||
| set(MD5 "dcbb02cc2da9653ec91860bb0594c91d") | |||
| elseif(PYTHON_VERSION MATCHES "3.7") | |||
| set(REQ_URL "https://gitee.com/mirrors/pybind11/repository/archive/v2.4.3.tar.gz") | |||
| set(MD5 "b473a37987ce456ea8cc7aab3f9486f9") | |||
| else() | |||
| message("Could not find 'Python 3.8' or 'Python 3.7'") | |||
| return() | |||
| endif() | |||
| else() | |||
| if(PYTHON_VERSION MATCHES "3.8") | |||
| set(REQ_URL "https://github.com/pybind/pybind11/archive/v2.6.1.tar.gz") | |||
| set(MD5 "32a7811f3db423df4ebfc731a28e5901") | |||
| elseif(PYTHON_VERSION MATCHES "3.7") | |||
| set(REQ_URL "https://github.com/pybind/pybind11/archive/v2.4.3.tar.gz") | |||
| set(MD5 "62254c40f89925bb894be421fe4cdef2") | |||
| else() | |||
| message("Could not find 'Python 3.8' or 'Python 3.7'") | |||
| return() | |||
| endif() | |||
| endif() | |||
| if(PYTHON_VERSION MATCHES "3.8") | |||
| set(PY_VER 2.6.1) | |||
| elseif(PYTHON_VERSION MATCHES "3.7") | |||
| set(PY_VER 2.4.3) | |||
| endif() | |||
| set(pybind11_CXXFLAGS "-D_FORTIFY_SOURCE=2 -O2") | |||
| set(pybind11_CFLAGS "-D_FORTIFY_SOURCE=2 -O2") | |||
| mindspore_add_pkg(pybind11 | |||
| VER 2.4.3 | |||
| URL https://github.com/pybind/pybind11/archive/v2.4.3.tar.gz | |||
| MD5 62254c40f89925bb894be421fe4cdef2 | |||
| VER ${PY_VER} | |||
| URL ${REQ_URL} | |||
| MD5 ${MD5} | |||
| CMAKE_OPTION -DPYBIND11_TEST=OFF -DPYBIND11_LTO_CXX_FLAGS=FALSE | |||
| ) | |||
| include_directories(${pybind11_INC}) | |||
| find_package(pybind11 REQUIRED) | |||
| set_property(TARGET pybind11::module PROPERTY IMPORTED_GLOBAL TRUE) | |||
| add_library(mindspore_serving::pybind11_module ALIAS pybind11::module) | |||
| add_library(mindspore::pybind11_module ALIAS pybind11::module) | |||
| @@ -1,65 +1,88 @@ | |||
| # find exec | |||
| find_package(Python3 3.7 COMPONENTS Interpreter) | |||
| if (NOT Python3_FOUND) | |||
| if(NOT Python3_FOUND) | |||
| message(FATAL_ERROR "No python3 found.") | |||
| endif () | |||
| endif() | |||
| set(PYTHON ${Python3_EXECUTABLE}) | |||
| set(PYTHON_VERSION ${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) | |||
| if (NOT PYTHON_VERSION MATCHES "3.7") | |||
| message(FATAL_ERROR "FIND PYTHON VERSION ${PYTHON_VERSION} BUT CAN NOT MATCH PYTHON VERSION 3.7") | |||
| endif () | |||
| if(NOT (PYTHON_VERSION MATCHES "3.8" OR PYTHON_VERSION MATCHES "3.7")) | |||
| message(FATAL_ERROR "FIND PYTHON VERSION ${PYTHON_VERSION} BUT CAN NOT MATCH PYTHON VERSION 3.8 OR 3.7") | |||
| endif() | |||
| find_package(Git) | |||
| if (NOT GIT_FOUND) | |||
| if(NOT GIT_FOUND) | |||
| message("No git found.") | |||
| return () | |||
| endif () | |||
| return() | |||
| endif() | |||
| set(GIT ${GIT_EXECUTABLE}) | |||
| # set path | |||
| set(MS_ROOT_DIR ${CPACK_PACKAGE_DIRECTORY}/../../) | |||
| set(MS_PACK_ROOT_DIR ${MS_ROOT_DIR}/build/package) | |||
| # set package file name | |||
| if (CMAKE_SYSTEM_NAME MATCHES "Linux") | |||
| if (PYTHON_VERSION MATCHES "3.7") | |||
| if(CMAKE_SYSTEM_NAME MATCHES "Linux") | |||
| if(PYTHON_VERSION MATCHES "3.8") | |||
| set(PY_TAGS "cp38-cp38") | |||
| elseif(PYTHON_VERSION MATCHES "3.7") | |||
| set(PY_TAGS "cp37-cp37m") | |||
| else () | |||
| message("Could not find 'Python 3.7'") | |||
| else() | |||
| message("Could not find 'Python 3.8' or 'Python 3.7'") | |||
| return() | |||
| endif () | |||
| endif() | |||
| string(TOLOWER linux_${CMAKE_HOST_SYSTEM_PROCESSOR} PLATFORM_TAG) | |||
| else () | |||
| elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") | |||
| if(PYTHON_VERSION MATCHES "3.8") | |||
| set(PY_TAGS "py38-none") | |||
| elseif(PYTHON_VERSION MATCHES "3.7") | |||
| set(PY_TAGS "py37-none") | |||
| else() | |||
| message("Could not find 'Python 3.8' or 'Python 3.7'") | |||
| return() | |||
| endif() | |||
| set(PLATFORM_TAG "any") | |||
| elseif(CMAKE_SYSTEM_NAME MATCHES "Windows") | |||
| if(PYTHON_VERSION MATCHES "3.8") | |||
| set(PY_TAGS "cp38-cp38") | |||
| elseif(PYTHON_VERSION MATCHES "3.7") | |||
| set(PY_TAGS "cp37-cp37m") | |||
| else() | |||
| message("Could not find 'Python 3.8' or 'Python 3.7'") | |||
| return() | |||
| endif() | |||
| set(PLATFORM_TAG "win_amd64") | |||
| else() | |||
| message(FATAL_ERROR "other platform: ${CMAKE_SYSTEM_NAME}") | |||
| endif () | |||
| endif() | |||
| # get git commit id | |||
| set(GIT_COMMIT_ID "") | |||
| execute_process( | |||
| COMMAND ${GIT} log --format='[sha1]:%h,[branch]:%d' --abbrev=8 -1 | |||
| OUTPUT_VARIABLE GIT_COMMIT_ID | |||
| WORKING_DIRECTORY ${MS_ROOT_DIR} | |||
| ERROR_QUIET) | |||
| COMMAND ${GIT} log --format='[sha1]:%h,[branch]:%d' --abbrev=8 -1 | |||
| OUTPUT_VARIABLE GIT_COMMIT_ID | |||
| WORKING_DIRECTORY ${MS_ROOT_DIR} | |||
| ERROR_QUIET) | |||
| string(REPLACE " " "" GIT_COMMIT_ID ${GIT_COMMIT_ID}) | |||
| set(ENV{MS_PACKAGE_NAME} ${CPACK_MS_PACKAGE_NAME}) | |||
| set(ENV{COMMIT_ID} ${GIT_COMMIT_ID}) | |||
| execute_process( | |||
| COMMAND ${PYTHON} ${MS_ROOT_DIR}/setup.py "bdist_wheel" | |||
| WORKING_DIRECTORY ${MS_PACK_ROOT_DIR} | |||
| COMMAND ${PYTHON} ${MS_ROOT_DIR}/setup.py "bdist_wheel" | |||
| WORKING_DIRECTORY ${MS_PACK_ROOT_DIR} | |||
| ) | |||
| # finally | |||
| set(PACKAGE_NAME ${CPACK_MS_PACKAGE_NAME}) | |||
| if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") | |||
| if(NOT CMAKE_SYSTEM_NAME MATCHES "Windows") | |||
| string(REPLACE "-" "_" PACKAGE_NAME ${PACKAGE_NAME}) | |||
| execute_process( | |||
| COMMAND chmod -R 700 ${MS_PACK_ROOT_DIR}/mindspore_serving/ | |||
| COMMAND chmod -R 700 ${MS_PACK_ROOT_DIR}/${PACKAGE_NAME}.egg-info/ | |||
| COMMAND chmod -R 700 ${MS_PACK_ROOT_DIR}/mindspore_serving/ | |||
| COMMAND chmod -R 700 ${MS_PACK_ROOT_DIR}/${PACKAGE_NAME}.egg-info/ | |||
| ) | |||
| endif () | |||
| endif() | |||
| file(GLOB WHL_FILE ${MS_PACK_ROOT_DIR}/dist/*.whl) | |||
| get_filename_component(ORIGIN_FILE_NAME ${WHL_FILE} NAME) | |||
| @@ -28,13 +28,14 @@ | |||
| #include "common/log.h" | |||
| #include "common/status.h" | |||
| #include "include/api/types.h" | |||
| #include "include/api/data_type.h" | |||
| namespace mindspore { | |||
| namespace serving { | |||
| using api::ModelType; | |||
| using api::ModelType::kMindIR; | |||
| using api::ModelType::kOM; | |||
| using mindspore::ModelType; | |||
| using mindspore::ModelType::kMindIR; | |||
| using mindspore::ModelType::kOM; | |||
| struct TensorInfo { | |||
| size_t size; // -1: unspecified | |||
| @@ -76,9 +77,6 @@ class MS_API InferSession { | |||
| virtual std::vector<TensorInfo> GetInputInfos(uint32_t model_id) const = 0; | |||
| virtual std::vector<TensorInfo> GetOutputInfos(uint32_t model_id) const = 0; | |||
| virtual ssize_t GetBatchSize(uint32_t model_id) const = 0; | |||
| virtual TensorBasePtr MakeInferenceTensor(DataType data_type, const std::vector<int64_t> &shape) const { | |||
| return nullptr; | |||
| } | |||
| virtual bool CheckModelSupport(DeviceType device_type, ModelType model_type) const { return true; } | |||
| }; | |||
| @@ -207,12 +205,12 @@ static inline LogStream &operator<<(LogStream &stream, DeviceType device_type) { | |||
| return stream; | |||
| } | |||
| static inline LogStream &operator<<(LogStream &stream, api::ModelType model_type) { | |||
| static inline LogStream &operator<<(LogStream &stream, mindspore::ModelType model_type) { | |||
| switch (model_type) { | |||
| case api::kMindIR: | |||
| case mindspore::kMindIR: | |||
| stream << "MindIR"; | |||
| break; | |||
| case api::kOM: | |||
| case mindspore::kOM: | |||
| stream << "OM"; | |||
| break; | |||
| default: | |||
| @@ -36,36 +36,44 @@ Status MindSporeModelWrap::FinalizeEnv() { | |||
| return SUCCESS; | |||
| } | |||
| api::DataType TransInferDataType2ApiTypeId(DataType data_type) { | |||
| const std::map<DataType, api::DataType> type2id_map{ | |||
| {serving::kMSI_Unknown, api::kMsUnknown}, {serving::kMSI_Bool, api::kMsBool}, | |||
| {serving::kMSI_Int8, api::kMsInt8}, {serving::kMSI_Uint8, api::kMsUint8}, | |||
| {serving::kMSI_Int16, api::kMsInt16}, {serving::kMSI_Uint16, api::kMsUint16}, | |||
| {serving::kMSI_Int32, api::kMsInt32}, {serving::kMSI_Uint32, api::kMsUint32}, | |||
| {serving::kMSI_Int64, api::kMsInt64}, {serving::kMSI_Uint64, api::kMsUint64}, | |||
| {serving::kMSI_Float16, api::kMsFloat16}, {serving::kMSI_Float32, api::kMsFloat32}, | |||
| {serving::kMSI_Float64, api::kMsFloat64}, | |||
| mindspore::DataType TransInferDataType2ApiTypeId(DataType data_type) { | |||
| const std::map<DataType, mindspore::DataType> type2id_map{ | |||
| {serving::kMSI_Unknown, mindspore::DataType::kTypeUnknown}, | |||
| {serving::kMSI_Bool, mindspore::DataType::kNumberTypeBool}, | |||
| {serving::kMSI_Int8, mindspore::DataType::kNumberTypeInt8}, | |||
| {serving::kMSI_Uint8, mindspore::DataType::kNumberTypeUInt8}, | |||
| {serving::kMSI_Int16, mindspore::DataType::kNumberTypeInt16}, | |||
| {serving::kMSI_Uint16, mindspore::DataType::kNumberTypeUInt16}, | |||
| {serving::kMSI_Int32, mindspore::DataType::kNumberTypeInt32}, | |||
| {serving::kMSI_Uint32, mindspore::DataType::kNumberTypeUInt32}, | |||
| {serving::kMSI_Int64, mindspore::DataType::kNumberTypeInt64}, | |||
| {serving::kMSI_Uint64, mindspore::DataType::kNumberTypeUInt64}, | |||
| {serving::kMSI_Float16, mindspore::DataType::kNumberTypeFloat16}, | |||
| {serving::kMSI_Float32, mindspore::DataType::kNumberTypeFloat32}, | |||
| {serving::kMSI_Float64, mindspore::DataType::kNumberTypeFloat64}, | |||
| }; | |||
| auto it = type2id_map.find(data_type); | |||
| if (it == type2id_map.end()) { | |||
| MSI_LOG_WARNING << "Unsupported MSI data type " << data_type; | |||
| return api::kMsUnknown; | |||
| return mindspore::DataType::kTypeUnknown; | |||
| } else { | |||
| return it->second; | |||
| } | |||
| } | |||
| DataType TransTypeId2InferDataType(api::DataType type_id) { | |||
| const std::map<api::DataType, DataType> id2type_map{ | |||
| {api::kMsUnknown, kMSI_Unknown}, {api::kMsBool, kMSI_Bool}, {api::kMsFloat64, kMSI_Float64}, | |||
| {api::kMsInt8, kMSI_Int8}, {api::kMsUint8, kMSI_Uint8}, {api::kMsInt16, kMSI_Int16}, | |||
| {api::kMsUint16, kMSI_Uint16}, {api::kMsInt32, kMSI_Int32}, {api::kMsUint32, kMSI_Uint32}, | |||
| {api::kMsInt64, kMSI_Int64}, {api::kMsUint64, kMSI_Uint64}, {api::kMsFloat16, kMSI_Float16}, | |||
| {api::kMsFloat32, kMSI_Float32}, | |||
| DataType TransTypeId2InferDataType(mindspore::DataType type_id) { | |||
| const std::map<mindspore::DataType, DataType> id2type_map{ | |||
| {mindspore::DataType::kTypeUnknown, kMSI_Unknown}, {mindspore::DataType::kNumberTypeBool, kMSI_Bool}, | |||
| {mindspore::DataType::kNumberTypeFloat64, kMSI_Float64}, {mindspore::DataType::kNumberTypeInt8, kMSI_Int8}, | |||
| {mindspore::DataType::kNumberTypeUInt8, kMSI_Uint8}, {mindspore::DataType::kNumberTypeInt16, kMSI_Int16}, | |||
| {mindspore::DataType::kNumberTypeUInt16, kMSI_Uint16}, {mindspore::DataType::kNumberTypeInt32, kMSI_Int32}, | |||
| {mindspore::DataType::kNumberTypeUInt32, kMSI_Uint32}, {mindspore::DataType::kNumberTypeInt64, kMSI_Int64}, | |||
| {mindspore::DataType::kNumberTypeUInt64, kMSI_Uint64}, {mindspore::DataType::kNumberTypeFloat16, kMSI_Float16}, | |||
| {mindspore::DataType::kNumberTypeFloat32, kMSI_Float32}, | |||
| }; | |||
| auto it = id2type_map.find(type_id); | |||
| if (it == id2type_map.end()) { | |||
| MSI_LOG_WARNING << "Unsupported data id " << type_id; | |||
| MSI_LOG_WARNING << "Unsupported data id " << static_cast<int>(type_id); | |||
| return kMSI_Unknown; | |||
| } else { | |||
| return it->second; | |||
| @@ -80,28 +88,30 @@ Status MindSporeModelWrap::LoadModelFromFile(serving::DeviceType device_type, ui | |||
| MSI_EXCEPTION_IF_NULL(model_id); | |||
| std::string device_type_str; | |||
| if (device_type == kDeviceTypeAscendMS) { | |||
| device_type_str = api::kDeviceTypeAscend910; | |||
| device_type_str = mindspore::kDeviceTypeAscend910; | |||
| } else if (device_type == kDeviceTypeAscendCL) { | |||
| device_type_str = api::kDeviceTypeAscend310; | |||
| device_type_str = mindspore::kDeviceTypeAscend310; | |||
| } else { | |||
| MSI_LOG_EXCEPTION << "Only support Ascend310 or Ascend910 in MindSporeModelWrap"; | |||
| } | |||
| std::shared_ptr<api::Model> model = nullptr; | |||
| std::shared_ptr<mindspore::Model> model = nullptr; | |||
| try { | |||
| api::Context::Instance().SetDeviceTarget(device_type_str).SetDeviceID(device_id); | |||
| auto graph = api::Serialization::LoadModel(file_name, model_type); | |||
| model = std::make_shared<api::Model>(api::GraphCell(graph)); | |||
| mindspore::GlobalContext::SetGlobalDeviceTarget(device_type_str); | |||
| mindspore::GlobalContext::SetGlobalDeviceID(device_id); | |||
| auto graph = mindspore::Serialization::LoadModel(file_name, model_type); | |||
| auto context = TransformModelContext(other_options); | |||
| model = std::make_shared<mindspore::Model>(mindspore::GraphCell(graph), context); | |||
| } catch (std::runtime_error &ex) { | |||
| MSI_LOG_ERROR << "Load model from file failed, model file: " << file_name << ", device_type: '" << device_type_str | |||
| << "', device_id: " << device_id << ", model type: " << model_type << ", options: " << other_options; | |||
| return FAILED; | |||
| } | |||
| api::Status status = model->Build(other_options); | |||
| if (!status.IsSuccess()) { | |||
| mindspore::Status status = model->Build(); | |||
| if (!status.IsOk()) { | |||
| MSI_LOG_ERROR << "Load model from file failed, model file: " << file_name << ", device_type: '" << device_type_str | |||
| << "', device_id: " << device_id << ", model type: " << model_type << ", options: " << other_options; | |||
| return Status(FAILED, status.StatusMessage()); | |||
| return Status(FAILED, status.ToString()); | |||
| } | |||
| model_index_++; | |||
| *model_id = model_index_; | |||
| @@ -120,6 +130,41 @@ Status MindSporeModelWrap::LoadModelFromFile(serving::DeviceType device_type, ui | |||
| return SUCCESS; | |||
| } | |||
| std::shared_ptr<Context> MindSporeModelWrap::TransformModelContext(const std::map<std::string, std::string> &options) { | |||
| using ContextStrFun = std::function<void(const std::shared_ptr<Context> &, const std::string &)>; | |||
| ContextStrFun set_output_type = [](const std::shared_ptr<Context> &context, const std::string &val) { | |||
| // "FP32", "FP16", "UINT8" | |||
| if (val == "FP32") { | |||
| mindspore::ModelContext::SetOutputType(context, mindspore::DataType::kNumberTypeFloat32); | |||
| } else if (val == "FP16") { | |||
| mindspore::ModelContext::SetOutputType(context, mindspore::DataType::kNumberTypeFloat16); | |||
| } else if (val == "UINT8") { | |||
| mindspore::ModelContext::SetOutputType(context, mindspore::DataType::kNumberTypeUInt8); | |||
| } else { | |||
| MSI_LOG_ERROR << "Set model context output type failed, unknown data type " << val; | |||
| } | |||
| }; | |||
| std::map<std::string, ContextStrFun> option_map = { | |||
| {"acl_option.insert_op_config_file_path", mindspore::ModelContext::SetInsertOpConfigPath}, | |||
| {"acl_option.input_format", mindspore::ModelContext::SetInputFormat}, | |||
| {"acl_option.input_shape", mindspore::ModelContext::SetInputShape}, | |||
| {"acl_option.output_type", set_output_type}, | |||
| {"acl_option.precision_mode", mindspore::ModelContext::SetPrecisionMode}, | |||
| {"acl_option.op_select_impl_mode", mindspore::ModelContext::SetOpSelectImplMode}, | |||
| }; | |||
| auto context = std::make_shared<mindspore::ModelContext>(); | |||
| for (auto &item : options) { | |||
| const auto &key = item.first; | |||
| const auto &value = item.second; | |||
| auto it = option_map.find(key); | |||
| if (it != option_map.end()) { | |||
| MSI_LOG_INFO << "Set context options, key: " << key << ", value: " << value; | |||
| it->second(context, value); | |||
| } | |||
| } | |||
| return context; | |||
| } | |||
| Status MindSporeModelWrap::GetModelInfos(ApiModelInfo *api_model_info) { | |||
| MSI_EXCEPTION_IF_NULL(api_model_info); | |||
| auto model = api_model_info->model; | |||
| @@ -138,70 +183,46 @@ Status MindSporeModelWrap::GetModelInfos(ApiModelInfo *api_model_info) { | |||
| } | |||
| } | |||
| }; | |||
| auto shape_element_num = [](const std::vector<int64_t> &shape) -> size_t { | |||
| size_t elements_nums = std::accumulate(shape.begin(), shape.end(), 1LL, std::multiplies<size_t>()); | |||
| return elements_nums; | |||
| }; | |||
| auto get_tensor_info_from_tensor = [find_batch_size, shape_element_num, api_model_info]( | |||
| const std::vector<int64_t> &shape, const api::DataType &data_type, | |||
| const size_t mem_size, int input_index = -1) { | |||
| auto get_tensor_info_from_tensor = [](const mindspore::MSTensor &ms_tensor) { | |||
| serving::TensorInfo tensor_info; | |||
| tensor_info.shape = shape; | |||
| tensor_info.data_type = TransTypeId2InferDataType(data_type); | |||
| tensor_info.size = mem_size; | |||
| tensor_info.shape = ms_tensor.Shape(); | |||
| tensor_info.data_type = TransTypeId2InferDataType(ms_tensor.DataType()); | |||
| tensor_info.size = ms_tensor.DataSize(); | |||
| if (tensor_info.size == 0) { | |||
| tensor_info.size = TensorBase::GetTypeSize(tensor_info.data_type) * shape_element_num(tensor_info.shape); | |||
| } | |||
| auto list = api_model_info->without_batch_dim_inputs; | |||
| if (std::find(list.begin(), list.end(), input_index) == list.end()) { | |||
| find_batch_size(tensor_info.shape); | |||
| auto &shape = tensor_info.shape; | |||
| size_t elements_nums = std::accumulate(shape.begin(), shape.end(), 1LL, std::multiplies<size_t>()); | |||
| tensor_info.size = TensorBase::GetTypeSize(tensor_info.data_type) * elements_nums; | |||
| } | |||
| return tensor_info; | |||
| }; | |||
| { // input infos | |||
| std::vector<std::string> names; | |||
| std::vector<std::vector<int64_t>> shapes; | |||
| std::vector<api::DataType> data_types; | |||
| std::vector<size_t> mem_sizes; | |||
| api::Status status = model->GetInputsInfo(&names, &shapes, &data_types, &mem_sizes); | |||
| if (!status.IsSuccess()) { | |||
| return Status(FAILED, status.StatusMessage()); | |||
| } | |||
| if (names.size() != shapes.size() || names.size() != data_types.size() || names.size() != mem_sizes.size()) { | |||
| return INFER_STATUS_LOG_ERROR(FAILED) | |||
| << "Get input infos failed, names size: " << names.size() << ", shapes size: " << shapes.size() | |||
| << ", data_types size: " << data_types.size() << ", mem_sizes: " << mem_sizes.size(); | |||
| } | |||
| for (size_t i = 0; i < names.size(); i++) { | |||
| api_model_info->input_names.push_back(names[i]); | |||
| auto tensor_info = get_tensor_info_from_tensor(shapes[i], data_types[i], mem_sizes[i], i); | |||
| auto input_infos = model->GetInputs(); | |||
| for (size_t i = 0; i < input_infos.size(); i++) { | |||
| auto &info = input_infos[i]; | |||
| auto tensor_info = get_tensor_info_from_tensor(info); | |||
| if (tensor_info.data_type == kMSI_Unknown) { | |||
| return INFER_STATUS_LOG_ERROR(FAILED) << "Unknown input api data type " << data_types[i]; | |||
| return INFER_STATUS_LOG_ERROR(FAILED) | |||
| << "Unknown input mindspore data type " << static_cast<int>(info.DataType()); | |||
| } | |||
| const auto &list = api_model_info->without_batch_dim_inputs; | |||
| if (std::find(list.begin(), list.end(), i) == list.end()) { | |||
| find_batch_size(tensor_info.shape); | |||
| } | |||
| api_model_info->input_tensor_infos.push_back(tensor_info); | |||
| api_model_info->input_names.push_back(info.Name()); | |||
| } | |||
| } | |||
| { // output infos | |||
| std::vector<std::string> names; | |||
| std::vector<std::vector<int64_t>> shapes; | |||
| std::vector<api::DataType> data_types; | |||
| std::vector<size_t> mem_sizes; | |||
| api::Status status = model->GetOutputsInfo(&names, &shapes, &data_types, &mem_sizes); | |||
| if (!status.IsSuccess()) { | |||
| return Status(FAILED, status.StatusMessage()); | |||
| } | |||
| if (names.size() != shapes.size() || names.size() != data_types.size() || names.size() != mem_sizes.size()) { | |||
| return INFER_STATUS_LOG_ERROR(FAILED) | |||
| << "Get output infos failed, names size: " << names.size() << ", shapes size: " << shapes.size() | |||
| << ", data_types size: " << data_types.size() << ", mem_sizes: " << mem_sizes.size(); | |||
| } | |||
| for (size_t i = 0; i < names.size(); i++) { | |||
| api_model_info->output_names.push_back(names[i]); | |||
| auto tensor_info = get_tensor_info_from_tensor(shapes[i], data_types[i], mem_sizes[i]); | |||
| auto output_infos = model->GetOutputs(); | |||
| for (auto &info : output_infos) { | |||
| auto tensor_info = get_tensor_info_from_tensor(info); | |||
| if (tensor_info.data_type == kMSI_Unknown) { | |||
| return INFER_STATUS_LOG_ERROR(FAILED) << "Unknown output api data type " << data_types[i]; | |||
| return INFER_STATUS_LOG_ERROR(FAILED) | |||
| << "Unknown output mindspore data type " << static_cast<int>(info.DataType()); | |||
| } | |||
| find_batch_size(tensor_info.shape); | |||
| api_model_info->output_tensor_infos.push_back(tensor_info); | |||
| api_model_info->output_names.push_back(info.Name()); | |||
| } | |||
| } | |||
| if (!first_dim_same) { | |||
| @@ -221,16 +242,21 @@ Status MindSporeModelWrap::UnloadModel(uint32_t model_id) { | |||
| Status MindSporeModelWrap::ExecuteModel(uint32_t model_id, const RequestBase &request, serving::ReplyBase *reply) { | |||
| MSI_EXCEPTION_IF_NULL(reply); | |||
| FuncMakeInBuffer func_in = [&request](size_t index) { | |||
| FuncMakeInBuffer func_in = [&request](size_t index, const std::string &name) { | |||
| auto input_tensor = request[index]; | |||
| return api::Buffer(input_tensor->data(), input_tensor->data_size()); | |||
| return mindspore::MSTensor::CreateRefTensor(name, TransInferDataType2ApiTypeId(input_tensor->data_type()), | |||
| input_tensor->shape(), const_cast<uint8_t *>(input_tensor->data()), | |||
| input_tensor->data_size()); | |||
| }; | |||
| FuncMakeOutTensor func_out = [&reply](const api::Buffer &result_tensor, DataType data_type, | |||
| FuncMakeOutTensor func_out = [&reply](const mindspore::MSTensor &result_tensor, DataType data_type, | |||
| const std::vector<int64_t> &shape) { | |||
| if (result_tensor.IsDevice()) { | |||
| MSI_LOG_EXCEPTION << "Can not support device type tensor"; | |||
| } | |||
| auto tensor = reply->add(); | |||
| MSI_EXCEPTION_IF_NULL(tensor); | |||
| tensor->set_data(result_tensor.Data(), result_tensor.DataSize()); | |||
| tensor->set_data(result_tensor.Data().get(), result_tensor.DataSize()); | |||
| tensor->set_data_type(data_type); | |||
| tensor->set_shape(shape); | |||
| }; | |||
| @@ -240,17 +266,17 @@ Status MindSporeModelWrap::ExecuteModel(uint32_t model_id, const RequestBase &re | |||
| Status MindSporeModelWrap::ExecuteModel(uint32_t model_id, const std::vector<TensorBasePtr> &request, | |||
| std::vector<TensorBasePtr> *reply) { | |||
| MSI_EXCEPTION_IF_NULL(reply); | |||
| FuncMakeInBuffer func_in = [&request](size_t index) { | |||
| FuncMakeInBuffer func_in = [&request](size_t index, const std::string &name) { | |||
| auto &input_tensor = request[index]; | |||
| auto api_buffer_wrap = std::dynamic_pointer_cast<ApiBufferTensorWrap>(input_tensor); | |||
| if (api_buffer_wrap) { | |||
| return api_buffer_wrap->GetBuffer(); | |||
| } else { | |||
| return api::Buffer(input_tensor->data(), input_tensor->data_size()); | |||
| } | |||
| return mindspore::MSTensor::CreateRefTensor(name, TransInferDataType2ApiTypeId(input_tensor->data_type()), | |||
| input_tensor->shape(), const_cast<uint8_t *>(input_tensor->data()), | |||
| input_tensor->data_size()); | |||
| }; | |||
| FuncMakeOutTensor func_out = [&reply](const api::Buffer &result_tensor, DataType data_type, | |||
| FuncMakeOutTensor func_out = [&reply](const mindspore::MSTensor &result_tensor, DataType data_type, | |||
| const std::vector<int64_t> &shape) { | |||
| if (result_tensor.IsDevice()) { | |||
| MSI_LOG_EXCEPTION << "Can not support device type tensor"; | |||
| } | |||
| auto tensor = std::make_shared<ApiBufferTensorWrap>(result_tensor); | |||
| tensor->set_data_type(data_type); | |||
| tensor->set_shape(shape); | |||
| @@ -273,14 +299,14 @@ Status MindSporeModelWrap::ExecuteModelCommon(uint32_t model_id, size_t request_ | |||
| return INFER_STATUS_LOG_ERROR(FAILED) << "Inputs size not match, request inputs size " << request_size | |||
| << ", model inputs size " << input_names.size(); | |||
| } | |||
| std::vector<api::Buffer> inputs; | |||
| std::vector<mindspore::MSTensor> inputs; | |||
| for (size_t i = 0; i < input_names.size(); i++) { | |||
| inputs.push_back(in_func(i)); | |||
| inputs.push_back(in_func(i, input_names[i])); | |||
| } | |||
| std::vector<api::Buffer> outputs; | |||
| api::Status status = model->Predict(inputs, &outputs); | |||
| if (!status.IsSuccess()) { | |||
| MSI_LOG_ERROR << "Predict failed: " << status.StatusMessage(); | |||
| std::vector<mindspore::MSTensor> outputs; | |||
| mindspore::Status status = model->Predict(inputs, &outputs); | |||
| if (!status.IsOk()) { | |||
| MSI_LOG_ERROR << "Predict failed: " << status.ToString(); | |||
| return FAILED; | |||
| } | |||
| if (outputs.size() != output_names.size()) { | |||
| @@ -331,34 +357,24 @@ ssize_t MindSporeModelWrap::GetBatchSize(uint32_t model_id) const { | |||
| return model_info.batch_size; | |||
| } | |||
| TensorBasePtr MindSporeModelWrap::MakeInferenceTensor(DataType data_type, const std::vector<int64_t> &shape) const { | |||
| return std::make_shared<ApiBufferTensorWrap>(data_type, shape); | |||
| } | |||
| bool MindSporeModelWrap::CheckModelSupport(DeviceType device_type, ModelType model_type) const { | |||
| std::string device_type_str; | |||
| switch (device_type) { | |||
| case kDeviceTypeAscendMS: | |||
| device_type_str = api::kDeviceTypeAscend910; | |||
| device_type_str = mindspore::kDeviceTypeAscend910; | |||
| break; | |||
| case kDeviceTypeAscendCL: | |||
| device_type_str = api::kDeviceTypeAscend310; | |||
| device_type_str = mindspore::kDeviceTypeAscend310; | |||
| break; | |||
| default: | |||
| return false; | |||
| } | |||
| return api::Model::CheckModelSupport(device_type_str, model_type); | |||
| return mindspore::Model::CheckModelSupport(device_type_str, model_type); | |||
| } | |||
| ApiBufferTensorWrap::ApiBufferTensorWrap() = default; | |||
| ApiBufferTensorWrap::ApiBufferTensorWrap(DataType type, const std::vector<int64_t> &shape) | |||
| : type_(type), shape_(shape) { | |||
| size_t data_len = itemsize() * TensorBase::element_cnt(); | |||
| buffer_.ResizeData(data_len); | |||
| } | |||
| ApiBufferTensorWrap::ApiBufferTensorWrap(const api::Buffer &buffer) : buffer_(buffer) {} | |||
| ApiBufferTensorWrap::ApiBufferTensorWrap(const mindspore::MSTensor &tensor) : tensor_(tensor) {} | |||
| ApiBufferTensorWrap::~ApiBufferTensorWrap() = default; | |||
| @@ -34,7 +34,7 @@ struct ApiModelInfo { | |||
| std::vector<serving::TensorInfo> input_tensor_infos; | |||
| std::vector<std::string> output_names; | |||
| std::vector<serving::TensorInfo> output_tensor_infos; | |||
| std::shared_ptr<api::Model> model; | |||
| std::shared_ptr<mindspore::Model> model; | |||
| uint32_t batch_size = 0; | |||
| std::string device_type; | |||
| uint32_t device_id = 0; | |||
| @@ -69,27 +69,25 @@ class MindSporeModelWrap : public InferSession { | |||
| ssize_t GetBatchSize(uint32_t model_id) const override; | |||
| TensorBasePtr MakeInferenceTensor(DataType data_type, const std::vector<int64_t> &shape) const override; | |||
| bool CheckModelSupport(DeviceType device_type, ModelType model_type) const override; | |||
| private: | |||
| std::unordered_map<uint32_t, ApiModelInfo> model_map_; | |||
| uint32_t model_index_ = 0; | |||
| using FuncMakeInBuffer = std::function<api::Buffer(size_t index)>; | |||
| using FuncMakeInBuffer = std::function<mindspore::MSTensor(size_t index, const std::string &name)>; | |||
| using FuncMakeOutTensor = | |||
| std::function<void(const api::Buffer, DataType data_type, const std::vector<int64_t> &shape)>; | |||
| std::function<void(const mindspore::MSTensor, DataType data_type, const std::vector<int64_t> &shape)>; | |||
| Status ExecuteModelCommon(uint32_t model_id, size_t request_size, const FuncMakeInBuffer &in_func, | |||
| const FuncMakeOutTensor &out_func); | |||
| Status GetModelInfos(ApiModelInfo *model_info); | |||
| std::shared_ptr<Context> TransformModelContext(const std::map<std::string, std::string> &other_options); | |||
| }; | |||
| class ApiBufferTensorWrap : public TensorBase { | |||
| public: | |||
| ApiBufferTensorWrap(); | |||
| ApiBufferTensorWrap(DataType type, const std::vector<int64_t> &shape); | |||
| explicit ApiBufferTensorWrap(const api::Buffer &buffer); | |||
| explicit ApiBufferTensorWrap(const mindspore::MSTensor &buffer); | |||
| ~ApiBufferTensorWrap() override; | |||
| void set_data_type(DataType type) override { type_ = type; } | |||
| @@ -98,28 +96,26 @@ class ApiBufferTensorWrap : public TensorBase { | |||
| void set_shape(const std::vector<int64_t> &shape) override { shape_ = shape; } | |||
| std::vector<int64_t> shape() const override { return shape_; } | |||
| const uint8_t *data() const override { return static_cast<const uint8_t *>(buffer_.Data()); } | |||
| size_t data_size() const override { return buffer_.DataSize(); } | |||
| const uint8_t *data() const override { return static_cast<const uint8_t *>(tensor_.Data().get()); } | |||
| size_t data_size() const override { return tensor_.DataSize(); } | |||
| bool resize_data(size_t data_len) override { return buffer_.ResizeData(data_len); } | |||
| uint8_t *mutable_data() override { return static_cast<uint8_t *>(buffer_.MutableData()); } | |||
| bool resize_data(size_t data_len) override { MSI_LOG_EXCEPTION << "ApiBufferTensorWrap not support resize data"; } | |||
| uint8_t *mutable_data() override { return static_cast<uint8_t *>(tensor_.MutableData()); } | |||
| // For kMSI_String and kMSI_Bytes | |||
| void clear_bytes_data() override { MSI_LOG_EXCEPTION << "Not support for api::Buffer Tensor"; } | |||
| void clear_bytes_data() override { MSI_LOG_EXCEPTION << "Not support for mindspore::Buffer Tensor"; } | |||
| void add_bytes_data(const uint8_t *data, size_t bytes_len) override { | |||
| MSI_LOG_EXCEPTION << "Not support for api::Buffer Tensor"; | |||
| MSI_LOG_EXCEPTION << "Not support for mindspore::MSTensor Tensor"; | |||
| } | |||
| size_t bytes_data_size() const override { MSI_LOG_EXCEPTION << "Not support for api::Buffer Tensor"; } | |||
| size_t bytes_data_size() const override { MSI_LOG_EXCEPTION << "Not support for mindspore::Buffer Tensor"; } | |||
| void get_bytes_data(size_t index, const uint8_t **data, size_t *bytes_len) const override { | |||
| MSI_LOG_EXCEPTION << "Not support for api::Buffer Tensor"; | |||
| MSI_LOG_EXCEPTION << "Not support for mindspore::MSTensor Tensor"; | |||
| } | |||
| api::Buffer GetBuffer() const { return buffer_; } | |||
| private: | |||
| DataType type_ = kMSI_Unknown; | |||
| std::vector<int64_t> shape_; | |||
| api::Buffer buffer_; | |||
| mindspore::MSTensor tensor_; | |||
| }; | |||
| } // namespace serving | |||
| @@ -30,8 +30,4 @@ std::vector<TensorInfo> AscendModelServable::GetOutputInfos() const { return ses | |||
| uint64_t AscendModelServable::GetBatchSize() const { return session_->GetBatchSize(model_id_); } | |||
| TensorBasePtr AscendModelServable::MakeInferenceTensor(DataType data_type, const std::vector<int64_t> &shape) const { | |||
| return session_->MakeInferenceTensor(data_type, shape); | |||
| } | |||
| } // namespace mindspore::serving | |||
| @@ -39,9 +39,6 @@ class ServableBase { | |||
| virtual std::vector<TensorInfo> GetInputInfos() const = 0; | |||
| virtual std::vector<TensorInfo> GetOutputInfos() const = 0; | |||
| virtual uint64_t GetBatchSize() const = 0; | |||
| virtual TensorBasePtr MakeInferenceTensor(DataType data_type, const std::vector<int64_t> &shape) const { | |||
| return nullptr; | |||
| } | |||
| }; | |||
| class AscendModelServable : public ServableBase { | |||
| @@ -55,7 +52,6 @@ class AscendModelServable : public ServableBase { | |||
| std::vector<TensorInfo> GetInputInfos() const override; | |||
| std::vector<TensorInfo> GetOutputInfos() const override; | |||
| uint64_t GetBatchSize() const override; | |||
| TensorBasePtr MakeInferenceTensor(DataType data_type, const std::vector<int64_t> &shape) const override; | |||
| private: | |||
| std::shared_ptr<serving::InferSession> session_{nullptr}; | |||
| @@ -192,14 +192,12 @@ void WorkExecutor::InitPrePostprocess() { | |||
| void WorkExecutor::InitInputTensors() { | |||
| inference_inputs_.clear(); | |||
| for (const auto &input_info : input_infos_) { | |||
| TensorBasePtr tensor = servable_->MakeInferenceTensor(input_info.data_type, input_info.shape); | |||
| if (tensor == nullptr) { | |||
| tensor = std::make_shared<Tensor>(); | |||
| tensor->set_data_type(input_info.data_type); | |||
| tensor->set_shape(input_info.shape); | |||
| tensor->resize_data(input_info.size); | |||
| } | |||
| for (size_t i = 0; i < input_infos_.size(); i++) { | |||
| auto &input_info = input_infos_[i]; | |||
| auto tensor = std::make_shared<Tensor>(); | |||
| tensor->set_data_type(input_info.data_type); | |||
| tensor->set_shape(input_info.shape); | |||
| tensor->resize_data(input_info.size); | |||
| inference_inputs_.push_back(tensor); | |||
| } | |||
| } | |||
| @@ -388,7 +386,7 @@ Status WorkExecutor::PostPredict(const std::vector<Instance> &inputs, const std: | |||
| for (auto &item : predict_result) { | |||
| size_t item_size = item->data_size() / model_batch_size; | |||
| if (item_size == 0) { | |||
| MSI_LOG_EXCEPTION << "Ouput result data size cannot be 0"; | |||
| MSI_LOG_EXCEPTION << "Output result data size cannot be 0"; | |||
| } | |||
| auto shape = item->shape(); | |||
| if (servable_declare_.servable_meta.with_batch_dim) { | |||
| @@ -28,7 +28,8 @@ def declare_servable(servable_file, model_format, with_batch_dim=True, options=N | |||
| Args: | |||
| servable_file (str): Model file name. | |||
| model_format (str): Model format, "OM" or "MindIR", case ignored. | |||
| with_batch_dim (bool): Whether the first shape dim of the inputs and outpus of model is batch dim, default True. | |||
| with_batch_dim (bool): Whether the first shape dim of the inputs and outputs of model is batch dim, | |||
| default True. | |||
| options (None, AclOptions, map): Options of model, currently AclOptions works. | |||
| without_batch_dim_inputs (None, int, tuple or list of int): Index of inputs that without batch dim | |||
| when with_batch_dim is True. | |||
| @@ -54,7 +55,8 @@ def declare_servable(servable_file, model_format, with_batch_dim=True, options=N | |||
| check_type.check_str("options key", k) | |||
| check_type.check_str(k + " value", w) | |||
| elif isinstance(options, AclOptions): | |||
| options = _as_options_map(options) | |||
| # pylint: disable=protected-access | |||
| options = options._as_options_map() | |||
| elif options is not None: | |||
| raise RuntimeError(f"Parameter 'options' should be None, dict of <str,str> or AclOptions, but " | |||
| f"gotten {type(options)}") | |||
| @@ -202,20 +204,19 @@ class AclOptions: | |||
| f"'high_precision', actually given '{val}'") | |||
| self.op_select_impl_mode = val | |||
| def _as_options_map(acl_options): | |||
| """Transfer AclOptions to dict of str,str""" | |||
| options = {} | |||
| if acl_options.insert_op_cfg_path: | |||
| options['mindspore.option.insert_op_config_file_path'] = acl_options.insert_op_cfg_path | |||
| if acl_options.input_format: | |||
| options['mindspore.option.input_format'] = acl_options.input_format | |||
| if acl_options.input_shape: | |||
| options['mindspore.option.input_shape'] = acl_options.input_shape | |||
| if acl_options.output_type: | |||
| options['mindspore.option.output_type'] = acl_options.output_type | |||
| if acl_options.precision_mode: | |||
| options['mindspore.option.precision_mode'] = acl_options.precision_mode | |||
| if acl_options.op_select_impl_mode: | |||
| options['mindspore.option.op_select_impl_mode'] = acl_options.op_select_impl_mode | |||
| return options | |||
| def _as_options_map(self): | |||
| """Transfer AclOptions to dict of str,str""" | |||
| options = {} | |||
| if self.insert_op_cfg_path: | |||
| options['acl_option.insert_op_config_file_path'] = self.insert_op_cfg_path | |||
| if self.input_format: | |||
| options['acl_option.input_format'] = self.input_format | |||
| if self.input_shape: | |||
| options['acl_option.input_shape'] = self.input_shape | |||
| if self.output_type: | |||
| options['acl_option.output_type'] = self.output_type | |||
| if self.precision_mode: | |||
| options['acl_option.precision_mode'] = self.precision_mode | |||
| if self.op_select_impl_mode: | |||
| options['acl_option.op_select_impl_mode'] = self.op_select_impl_mode | |||
| return options | |||
| @@ -79,6 +79,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) | |||
| include_directories(stub) | |||
| include_directories(stub/include) | |||
| include_directories(${CMAKE_SOURCE_DIR}) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../third_party) | |||
| include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../mindspore_serving/ccsrc) | |||
| link_directories(${CMKAE_BINARY_DIR}/securec/src) | |||
| @@ -375,7 +375,7 @@ def test_grpc_larger_than_server_receive_max_size(): | |||
| base = ServingTestBase() | |||
| base.init_servable(1, "add_servable_config.py") | |||
| worker.start_servable_in_master(base.servable_dir, base.servable_name, 0) | |||
| master.start_grpc_server("0.0.0.0", 5500, max_msg_mb_size=1) # 1MB | |||
| master.start_grpc_server("0.0.0.0", 5500, max_msg_mb_size=1) # 1MB | |||
| # Client | |||
| client = create_client("localhost", 5500, base.servable_name, "add_common") | |||
| instances = [] | |||
| @@ -385,7 +385,7 @@ def test_grpc_larger_than_server_receive_max_size(): | |||
| x2 = np.ones([1024, 1024], np.float32) | |||
| y_data_list.append(x1 + x2) | |||
| instances.append({"x1": x1, "x2": x2}) | |||
| result = client.infer(instances) # more than 1MB msg | |||
| result = client.infer(instances) # more than 1MB msg | |||
| print(result) | |||
| assert "Grpc Error, (8, 'resource exhausted')" in str(result["error"]) | |||
| @@ -350,7 +350,7 @@ def test_restful_request_larger_than_server_receive_max_size(): | |||
| base = ServingTestBase() | |||
| base.init_servable(1, "add_servable_config.py") | |||
| worker.start_servable_in_master(base.servable_dir, base.servable_name, 0) | |||
| master.start_restful_server("0.0.0.0", 5500, max_msg_mb_size=1) # 1MB | |||
| master.start_restful_server("0.0.0.0", 5500, max_msg_mb_size=1) # 1MB | |||
| # Client | |||
| instances = [] | |||
| x1 = np.ones([1024, 1024], np.float32) | |||
| @@ -18,7 +18,7 @@ | |||
| #include "cxx_api/factory.h" | |||
| #include "cxx_api/graph/graph_impl.h" | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| std::vector<Output> CellBase::operator()(const std::vector<Input> &inputs) const { return Clone()->Construct(inputs); } | |||
| ParameterCell::ParameterCell(const ParameterCell &cell) : tensor_(cell.tensor_.Clone()) {} | |||
| @@ -40,23 +40,23 @@ ParameterCell &ParameterCell::operator=(ParameterCell &&cell) { | |||
| return *this; | |||
| } | |||
| ParameterCell::ParameterCell(const Tensor &tensor) : tensor_(tensor.Clone()) {} | |||
| ParameterCell::ParameterCell(const MSTensor &tensor) : tensor_(tensor.Clone()) {} | |||
| ParameterCell &ParameterCell::operator=(const Tensor &tensor) { | |||
| ParameterCell &ParameterCell::operator=(const MSTensor &tensor) { | |||
| tensor_ = tensor.Clone(); | |||
| return *this; | |||
| } | |||
| ParameterCell::ParameterCell(Tensor &&tensor) : tensor_(tensor) {} | |||
| ParameterCell::ParameterCell(MSTensor &&tensor) : tensor_(tensor) {} | |||
| ParameterCell &ParameterCell::operator=(Tensor &&tensor) { | |||
| ParameterCell &ParameterCell::operator=(MSTensor &&tensor) { | |||
| tensor_ = tensor; | |||
| return *this; | |||
| } | |||
| GraphCell::GraphCell(const Graph &graph) | |||
| : graph_(std::make_shared<Graph>(graph)), | |||
| executor_(Factory<GraphCell::GraphImpl>::Instance().Create(Context::Instance().GetDeviceTarget())) { | |||
| executor_(Factory<GraphCell::GraphImpl>::Instance().Create(GlobalContext::GetGlobalDeviceTarget())) { | |||
| MS_EXCEPTION_IF_NULL(graph_); | |||
| MS_EXCEPTION_IF_NULL(executor_); | |||
| executor_->SetGraph(graph_); | |||
| @@ -64,7 +64,7 @@ GraphCell::GraphCell(const Graph &graph) | |||
| GraphCell::GraphCell(const std::shared_ptr<Graph> &graph) | |||
| : graph_(graph), | |||
| executor_(Factory<GraphCell::GraphImpl>::Instance().Create(Context::Instance().GetDeviceTarget())) { | |||
| executor_(Factory<GraphCell::GraphImpl>::Instance().Create(GlobalContext::GetGlobalDeviceTarget())) { | |||
| MS_EXCEPTION_IF_NULL(graph_); | |||
| MS_EXCEPTION_IF_NULL(executor_); | |||
| executor_->SetGraph(graph_); | |||
| @@ -72,13 +72,13 @@ GraphCell::GraphCell(const std::shared_ptr<Graph> &graph) | |||
| GraphCell::GraphCell(Graph &&graph) | |||
| : graph_(std::make_shared<Graph>(graph)), | |||
| executor_(Factory<GraphCell::GraphImpl>::Instance().Create(Context::Instance().GetDeviceTarget())) { | |||
| executor_(Factory<GraphCell::GraphImpl>::Instance().Create(GlobalContext::GetGlobalDeviceTarget())) { | |||
| MS_EXCEPTION_IF_NULL(graph_); | |||
| MS_EXCEPTION_IF_NULL(executor_); | |||
| executor_->SetGraph(graph_); | |||
| } | |||
| Status GraphCell::Run(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) { | |||
| Status GraphCell::Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) { | |||
| MS_EXCEPTION_IF_NULL(executor_); | |||
| return executor_->Run(inputs, outputs); | |||
| } | |||
| @@ -88,25 +88,24 @@ Status GraphCell::Load() { | |||
| return executor_->Load(); | |||
| } | |||
| Status GraphCell::GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const { | |||
| std::vector<MSTensor> GraphCell::GetInputs() { | |||
| MS_EXCEPTION_IF_NULL(executor_); | |||
| return executor_->GetInputsInfo(names, shapes, data_types, mem_sizes); | |||
| return executor_->GetInputs(); | |||
| } | |||
| Status GraphCell::GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const { | |||
| std::vector<MSTensor> GraphCell::GetOutputs() { | |||
| MS_EXCEPTION_IF_NULL(executor_); | |||
| return executor_->GetOutputsInfo(names, shapes, data_types, mem_sizes); | |||
| return executor_->GetOutputs(); | |||
| } | |||
| InputAndOutput::InputAndOutput() : cell_(nullptr), prev_(), index_(-1) {} | |||
| InputAndOutput::InputAndOutput(const Tensor &tensor) | |||
| InputAndOutput::InputAndOutput(const MSTensor &tensor) | |||
| : cell_(std::make_shared<ParameterCell>(tensor.Clone())), prev_(), index_(-1) {} | |||
| InputAndOutput::InputAndOutput(Tensor &&tensor) : cell_(std::make_shared<ParameterCell>(tensor)), prev_(), index_(-1) {} | |||
| InputAndOutput::InputAndOutput(MSTensor &&tensor) | |||
| : cell_(std::make_shared<ParameterCell>(tensor)), prev_(), index_(-1) {} | |||
| InputAndOutput::InputAndOutput(const std::shared_ptr<CellBase> &cell, const std::vector<InputAndOutput> &prev, | |||
| int32_t index) | |||
| : cell_(cell), prev_(prev), index_(index) {} | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| @@ -14,50 +14,121 @@ | |||
| * limitations under the License. | |||
| */ | |||
| #include "include/api/context.h" | |||
| #include "utils/log_adapter.h" | |||
| namespace mindspore::api { | |||
| class Context::ContextImpl { | |||
| public: | |||
| ContextImpl() : device_target_("NotSet"), device_id_(0) {} | |||
| ~ContextImpl() = default; | |||
| const std::string &GetDeviceTarget() const { return device_target_; } | |||
| void SetDeviceTarget(std::string_view device_target) { device_target_ = device_target; } | |||
| uint32_t GetDeviceID() const { return device_id_; } | |||
| void SetDeviceID(uint32_t device_id) { device_id_ = device_id; } | |||
| constexpr auto kGlobalContextDeviceTarget = "mindspore.ascend.globalcontext.device_target"; | |||
| constexpr auto kGlobalContextDeviceID = "mindspore.ascend.globalcontext.device_id"; | |||
| constexpr auto kModelOptionInsertOpCfgPath = "mindspore.option.insert_op_config_file_path"; // aipp config file | |||
| constexpr auto kModelOptionInputFormat = "mindspore.option.input_format"; // nchw or nhwc | |||
| constexpr auto kModelOptionInputShape = "mindspore.option.input_shape"; | |||
| // Mandatory while dynamic batch: e.g. "input_op_name1: n1,c2,h3,w4;input_op_name2: n4,c3,h2,w1" | |||
| constexpr auto kModelOptionOutputType = "mindspore.option.output_type"; // "FP32", "UINT8" or "FP16", default as "FP32" | |||
| constexpr auto kModelOptionPrecisionMode = "mindspore.option.precision_mode"; | |||
| // "force_fp16", "allow_fp32_to_fp16", "must_keep_origin_dtype" or "allow_mix_precision", default as "force_fp16" | |||
| constexpr auto kModelOptionOpSelectImplMode = "mindspore.option.op_select_impl_mode"; | |||
| private: | |||
| std::string device_target_; | |||
| uint32_t device_id_; | |||
| }; | |||
| namespace mindspore { | |||
| template <class T> | |||
| static T GetValue(const std::shared_ptr<Context> &context, const std::string &key) { | |||
| auto iter = context->params.find(key); | |||
| if (iter == context->params.end()) { | |||
| return T(); | |||
| } | |||
| const std::any &value = iter->second; | |||
| if (value.type() != typeid(T)) { | |||
| return T(); | |||
| } | |||
| Context &Context::Instance() { | |||
| static Context context; | |||
| return context; | |||
| return std::any_cast<T>(value); | |||
| } | |||
| const std::string &Context::GetDeviceTarget() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->GetDeviceTarget(); | |||
| std::shared_ptr<Context> GlobalContext::GetGlobalContext() { | |||
| static std::shared_ptr<Context> g_context = std::make_shared<Context>(); | |||
| return g_context; | |||
| } | |||
| Context &Context::SetDeviceTarget(const std::string &device_target) { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| impl_->SetDeviceTarget(device_target); | |||
| return *this; | |||
| void GlobalContext::SetGlobalDeviceTarget(const std::string &device_target) { | |||
| auto global_context = GetGlobalContext(); | |||
| MS_EXCEPTION_IF_NULL(global_context); | |||
| global_context->params[kGlobalContextDeviceTarget] = device_target; | |||
| } | |||
| uint32_t Context::GetDeviceID() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->GetDeviceID(); | |||
| std::string GlobalContext::GetGlobalDeviceTarget() { | |||
| auto global_context = GetGlobalContext(); | |||
| MS_EXCEPTION_IF_NULL(global_context); | |||
| return GetValue<std::string>(global_context, kGlobalContextDeviceTarget); | |||
| } | |||
| Context &Context::SetDeviceID(uint32_t device_id) { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| impl_->SetDeviceID(device_id); | |||
| return *this; | |||
| void GlobalContext::SetGlobalDeviceID(const uint32_t &device_id) { | |||
| auto global_context = GetGlobalContext(); | |||
| MS_EXCEPTION_IF_NULL(global_context); | |||
| global_context->params[kGlobalContextDeviceID] = device_id; | |||
| } | |||
| Context::Context() : impl_(std::make_shared<Context::ContextImpl>()) { MS_EXCEPTION_IF_NULL(impl_); } | |||
| uint32_t GlobalContext::GetGlobalDeviceID() { | |||
| auto global_context = GetGlobalContext(); | |||
| MS_EXCEPTION_IF_NULL(global_context); | |||
| return GetValue<uint32_t>(global_context, kGlobalContextDeviceID); | |||
| } | |||
| void ModelContext::SetInsertOpConfigPath(const std::shared_ptr<Context> &context, const std::string &cfg_path) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| context->params[kModelOptionInsertOpCfgPath] = cfg_path; | |||
| } | |||
| std::string ModelContext::GetInsertOpConfigPath(const std::shared_ptr<Context> &context) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| return GetValue<std::string>(context, kModelOptionInsertOpCfgPath); | |||
| } | |||
| void ModelContext::SetInputFormat(const std::shared_ptr<Context> &context, const std::string &format) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| context->params[kModelOptionInputFormat] = format; | |||
| } | |||
| std::string ModelContext::GetInputFormat(const std::shared_ptr<Context> &context) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| return GetValue<std::string>(context, kModelOptionInputFormat); | |||
| } | |||
| void ModelContext::SetInputShape(const std::shared_ptr<Context> &context, const std::string &shape) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| context->params[kModelOptionInputShape] = shape; | |||
| } | |||
| std::string ModelContext::GetInputShape(const std::shared_ptr<Context> &context) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| return GetValue<std::string>(context, kModelOptionInputShape); | |||
| } | |||
| void ModelContext::SetOutputType(const std::shared_ptr<Context> &context, enum DataType output_type) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| context->params[kModelOptionOutputType] = output_type; | |||
| } | |||
| enum DataType ModelContext::GetOutputType(const std::shared_ptr<Context> &context) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| return GetValue<enum DataType>(context, kModelOptionOutputType); | |||
| } | |||
| void ModelContext::SetPrecisionMode(const std::shared_ptr<Context> &context, const std::string &precision_mode) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| context->params[kModelOptionPrecisionMode] = precision_mode; | |||
| } | |||
| std::string ModelContext::GetPrecisionMode(const std::shared_ptr<Context> &context) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| return GetValue<std::string>(context, kModelOptionPrecisionMode); | |||
| } | |||
| Context::~Context() {} | |||
| } // namespace mindspore::api | |||
| void ModelContext::SetOpSelectImplMode(const std::shared_ptr<Context> &context, | |||
| const std::string &op_select_impl_mode) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| context->params[kModelOptionOpSelectImplMode] = op_select_impl_mode; | |||
| } | |||
| std::string ModelContext::GetOpSelectImplMode(const std::shared_ptr<Context> &context) { | |||
| MS_EXCEPTION_IF_NULL(context); | |||
| return GetValue<std::string>(context, kModelOptionOpSelectImplMode); | |||
| } | |||
| } // namespace mindspore | |||
| @@ -21,12 +21,9 @@ | |||
| #include <vector> | |||
| #include <memory> | |||
| #include <utility> | |||
| #include "common/status.h" | |||
| #include "utils/utils.h" | |||
| #define MS_LOG MSI_LOG | |||
| #define MS_EXCEPTION_IF_NULL MSI_EXCEPTION_IF_NULL | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| template <class T> | |||
| class Factory { | |||
| using U = std::function<std::shared_ptr<T>()>; | |||
| @@ -82,5 +79,5 @@ class Registrar { | |||
| #define API_FACTORY_REG(BASE_CLASS, DEVICE_NAME, DERIVE_CLASS) \ | |||
| static const Registrar<BASE_CLASS> g_api_##DERIVE_CLASS##_registrar_##DEVICE_NAME##_reg( \ | |||
| #DEVICE_NAME, []() { return std::make_shared<DERIVE_CLASS>(); }); | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_CXX_API_FACTORY_H | |||
| @@ -15,16 +15,21 @@ | |||
| */ | |||
| #include "include/api/graph.h" | |||
| #include "cxx_api/graph/graph_data.h" | |||
| #include "utils/log_adapter.h" | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| Graph::Graph(const std::shared_ptr<GraphData> &graph_data) : graph_data_(graph_data) {} | |||
| Graph::Graph(std::shared_ptr<GraphData> &&graph_data) : graph_data_(graph_data) {} | |||
| Graph::~Graph() {} | |||
| Graph::Graph(std::nullptr_t) : graph_data_(nullptr) {} | |||
| bool Graph::operator==(std::nullptr_t) const { return graph_data_ == nullptr; } | |||
| ModelType Graph::ModelType() const { | |||
| MS_EXCEPTION_IF_NULL(graph_data_); | |||
| return graph_data_->ModelType(); | |||
| } | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| @@ -14,8 +14,12 @@ | |||
| * limitations under the License. | |||
| */ | |||
| #include "cxx_api/graph/graph_data.h" | |||
| #include "utils/log_adapter.h" | |||
| #ifdef ENABLE_ACL | |||
| #include "framework/common/helper/model_helper.h" | |||
| #endif | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| Graph::GraphData::GraphData(const FuncGraphPtr &func_graph, enum ModelType model_type) | |||
| : func_graph_(nullptr), om_data_(), model_type_(ModelType::kUnknownType) { | |||
| if (model_type != ModelType::kMindIR) { | |||
| @@ -30,6 +34,23 @@ Graph::GraphData::GraphData(Buffer om_data, enum ModelType model_type) | |||
| if (model_type != ModelType::kOM) { | |||
| MS_LOG(EXCEPTION) << "Invalid ModelType " << model_type; | |||
| } | |||
| #ifdef ENABLE_ACL | |||
| // check om | |||
| ge::ModelHelper helper; | |||
| ge::ModelData model_data; | |||
| model_data.model_data = om_data.MutableData(); | |||
| model_data.model_len = om_data.DataSize(); | |||
| ge::Status ret = helper.LoadModel(model_data); | |||
| if (ret != ge::SUCCESS) { | |||
| MS_LOG(EXCEPTION) << "Invalid input data cannot parse to om."; | |||
| } | |||
| om_data_ = om_data; | |||
| model_type_ = model_type; | |||
| #else | |||
| MS_LOG(EXCEPTION) << "Unsupported ModelType OM."; | |||
| #endif | |||
| } | |||
| Graph::GraphData::~GraphData() {} | |||
| @@ -51,4 +72,4 @@ Buffer Graph::GraphData::GetOMData() const { | |||
| return om_data_; | |||
| } | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| @@ -22,8 +22,9 @@ | |||
| #include <memory> | |||
| #include "include/api/graph.h" | |||
| #include "include/api/types.h" | |||
| #include "utils/utils.h" | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| class Graph::GraphData { | |||
| public: | |||
| GraphData(); | |||
| @@ -45,5 +46,5 @@ class Graph::GraphData { | |||
| Buffer om_data_; | |||
| enum ModelType model_type_; | |||
| }; | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_CXX_API_GRAPH_GRAPH_DATA_H | |||
| @@ -24,8 +24,9 @@ | |||
| #include "include/api/cell.h" | |||
| #include "include/api/graph.h" | |||
| #include "cxx_api/graph/graph_data.h" | |||
| #include "utils/utils.h" | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| class GraphCell::GraphImpl { | |||
| public: | |||
| GraphImpl() = default; | |||
| @@ -34,17 +35,14 @@ class GraphCell::GraphImpl { | |||
| std::shared_ptr<Graph::GraphData> &MutableGraphData() const { return graph_->graph_data_; } | |||
| void SetGraph(const std::shared_ptr<Graph> &graph) { graph_ = graph; } | |||
| virtual Status Run(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) = 0; | |||
| virtual Status Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) = 0; | |||
| virtual Status Load() = 0; | |||
| virtual Status GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) = 0; | |||
| virtual Status GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) = 0; | |||
| virtual std::vector<MSTensor> GetInputs() = 0; | |||
| virtual std::vector<MSTensor> GetOutputs() = 0; | |||
| protected: | |||
| std::shared_ptr<Graph> graph_; | |||
| }; | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_CXX_API_GRAPH_GRAPH_IMPL_H | |||
| @@ -19,7 +19,7 @@ | |||
| #include "cxx_api/factory.h" | |||
| #include "stub/graph_impl_stub.h" | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| API_FACTORY_REG(GraphCell::GraphImpl, Ascend910, MsGraphImpl); | |||
| std::shared_ptr<GraphCell::GraphImpl> MsGraphImpl::graph_imp_stub_ = std::make_shared<GraphImplStubAdd>(); | |||
| @@ -28,28 +28,27 @@ MsGraphImpl::MsGraphImpl() {} | |||
| MsGraphImpl::~MsGraphImpl() {} | |||
| Status MsGraphImpl::GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) { | |||
| std::vector<MSTensor> MsGraphImpl::GetInputs() { | |||
| if (!graph_imp_stub_) { | |||
| return FAILED; | |||
| return {}; | |||
| } | |||
| return graph_imp_stub_->GetInputsInfo(names, shapes, data_types, mem_sizes); | |||
| return graph_imp_stub_->GetInputs(); | |||
| } | |||
| Status MsGraphImpl::GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) { | |||
| std::vector<MSTensor> MsGraphImpl::GetOutputs() { | |||
| if (!graph_imp_stub_) { | |||
| return FAILED; | |||
| return {}; | |||
| } | |||
| return graph_imp_stub_->GetOutputsInfo(names, shapes, data_types, mem_sizes); | |||
| return graph_imp_stub_->GetOutputs(); | |||
| } | |||
| Status MsGraphImpl::Load() { return SUCCESS; } | |||
| Status MsGraphImpl::Load() { return kSuccess; } | |||
| Status MsGraphImpl::Run(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) { | |||
| Status MsGraphImpl::Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) { | |||
| if (!graph_imp_stub_) { | |||
| return FAILED; | |||
| return kMCFailed; | |||
| } | |||
| return graph_imp_stub_->Run(inputs, outputs); | |||
| } | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| @@ -21,25 +21,26 @@ | |||
| #include <vector> | |||
| #include <memory> | |||
| #include <utility> | |||
| #include <mutex> | |||
| #include "include/api/status.h" | |||
| #include "include/api/graph.h" | |||
| #include "cxx_api/graph/graph_impl.h" | |||
| #include "cxx_api/model/model_impl.h" | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| class MsGraphImpl : public GraphCell::GraphImpl { | |||
| public: | |||
| MsGraphImpl(); | |||
| ~MsGraphImpl() override; | |||
| Status Run(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) override; | |||
| Status Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) override; | |||
| Status Load() override; | |||
| Status GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) override; | |||
| Status GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) override; | |||
| std::vector<MSTensor> GetInputs() override; | |||
| std::vector<MSTensor> GetOutputs() override; | |||
| private: | |||
| static std::shared_ptr<GraphCell::GraphImpl> graph_imp_stub_; | |||
| }; | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_CXX_API_GRAPH_MS_MS_GRAPH_IMPL_H | |||
| @@ -18,49 +18,45 @@ | |||
| #include "cxx_api/model/model_impl.h" | |||
| #include "cxx_api/factory.h" | |||
| namespace mindspore::api { | |||
| Status Model::Build(const std::map<std::string, std::string> &options) { | |||
| namespace mindspore { | |||
| Status Model::Build() { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->Build(options); | |||
| return impl_->Build(); | |||
| } | |||
| Status Model::Train(const DataSet &dataset, bool data_sink, std::map<std::string, Buffer> *outputs) { | |||
| Status Model::Resize(const std::vector<MSTensor> &inputs, const std::vector<std::vector<int64_t>> &dims) { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->Train(dataset, outputs); | |||
| return impl_->Resize(inputs, dims); | |||
| } | |||
| Status Model::Eval(const DataSet &dataset, bool data_sink, std::map<std::string, Buffer> *outputs) { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->Eval(dataset, outputs); | |||
| } | |||
| Status Model::Predict(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) { | |||
| Status Model::Predict(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->Predict(inputs, outputs); | |||
| } | |||
| Status Model::GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const { | |||
| std::vector<MSTensor> Model::GetInputs() { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->GetInputsInfo(names, shapes, data_types, mem_sizes); | |||
| return impl_->GetInputs(); | |||
| } | |||
| Status Model::GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const { | |||
| std::vector<MSTensor> Model::GetOutputs() { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->GetOutputsInfo(names, shapes, data_types, mem_sizes); | |||
| return impl_->GetOutputs(); | |||
| } | |||
| Model::Model(const GraphCell &graph_cell) | |||
| : impl_(Factory<ModelImpl>::Instance().Create(Context::Instance().GetDeviceTarget())) { | |||
| Model::Model(const GraphCell &graph_cell, const std::shared_ptr<Context> &model_context) | |||
| : impl_(Factory<ModelImpl>::Instance().Create(mindspore::GlobalContext::GetGlobalDeviceTarget())) { | |||
| if (impl_ == nullptr) { | |||
| MS_LOG(EXCEPTION) << "Create session type " << Context::Instance().GetDeviceTarget() << " failed"; | |||
| MS_LOG(EXCEPTION) << "Create session type " << mindspore::GlobalContext::GetGlobalDeviceTarget() << " failed"; | |||
| } | |||
| MS_EXCEPTION_IF_NULL(graph_cell.GetGraph()); | |||
| impl_->SetGraph(std::make_shared<Graph>(*graph_cell.GetGraph())); | |||
| impl_->SetContext(model_context); | |||
| } | |||
| Model::Model(const std::vector<Output> &network) { MS_LOG(EXCEPTION) << "Unsupported feature."; } | |||
| Model::Model(const std::vector<Output> &network, const std::shared_ptr<Context> &model_context) { | |||
| MS_LOG(EXCEPTION) << "Unsupported feature."; | |||
| } | |||
| Model::~Model() {} | |||
| @@ -68,4 +64,4 @@ bool Model::CheckModelSupport(const std::string &device_type, ModelType) { | |||
| return Factory<ModelImpl>::Instance().CheckModelSupport(device_type); | |||
| } | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| @@ -21,26 +21,24 @@ | |||
| #include <vector> | |||
| #include <memory> | |||
| #include <utility> | |||
| #include "include/api/context.h" | |||
| #include "include/api/model.h" | |||
| #include "include/api/graph.h" | |||
| #include "cxx_api/graph/graph_data.h" | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| class ModelImpl { | |||
| public: | |||
| ModelImpl() = default; | |||
| virtual ~ModelImpl() = default; | |||
| virtual Status Build(const std::map<std::string, std::string> &options) = 0; | |||
| virtual Status Build() = 0; | |||
| virtual Status Resize(const std::vector<MSTensor> &inputs, const std::vector<std::vector<int64_t>> &dims) = 0; | |||
| virtual Status Train(const DataSet &dataset, std::map<std::string, Buffer> *outputs) = 0; | |||
| virtual Status Eval(const DataSet &dataset, std::map<std::string, Buffer> *outputs) = 0; | |||
| virtual Status Predict(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) = 0; | |||
| virtual Status Predict(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) = 0; | |||
| virtual Status GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const = 0; | |||
| virtual Status GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const = 0; | |||
| virtual std::vector<MSTensor> GetInputs() = 0; | |||
| virtual std::vector<MSTensor> GetOutputs() = 0; | |||
| protected: | |||
| Status Load(const std::shared_ptr<GraphCell> &graph_cell) { | |||
| @@ -59,11 +57,14 @@ class ModelImpl { | |||
| } | |||
| std::shared_ptr<Graph> graph_; | |||
| std::shared_ptr<Context> model_context_; | |||
| private: | |||
| friend class Model; | |||
| void SetGraph(const std::shared_ptr<Graph> &graph) { graph_ = graph; } | |||
| void SetContext(const std::shared_ptr<Context> &model_context) { | |||
| model_context_ = std::make_shared<Context>(*model_context); | |||
| } | |||
| }; | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_CXX_API_MODEL_MODEL_IMPL_H | |||
| @@ -16,13 +16,53 @@ | |||
| #include "cxx_api/model/ms/ms_model.h" | |||
| #include <memory> | |||
| #include "include/api/context.h" | |||
| #include "cxx_api/factory.h" | |||
| namespace mindspore { | |||
| namespace api { | |||
| API_FACTORY_REG(ModelImpl, Ascend910, MsModel); | |||
| Status MsModel::Build(const std::map<std::string, std::string> &) { | |||
| static std::string GenerateShapeKey(const std::vector<std::vector<int64_t>> &dims) { | |||
| std::string shape_key; | |||
| for (size_t i = 0; i < dims.size(); ++i) { | |||
| shape_key += std::to_string(i) + ":"; | |||
| for (size_t j = 0; j < dims[i].size(); ++j) { | |||
| shape_key += std::to_string(dims[i][j]); | |||
| if (j + 1 < dims[i].size()) { | |||
| shape_key += ","; | |||
| } | |||
| } | |||
| if (i + 1 < dims.size()) { | |||
| shape_key += ";"; | |||
| } | |||
| } | |||
| return shape_key; | |||
| } | |||
| std::shared_ptr<GraphCell> MsModel::GenerateGraphCell(const std::vector<std::vector<int64_t>> &dims) { | |||
| std::string shape_key = GenerateShapeKey(dims); | |||
| if (auto iter = dynamic_size_graph_map_.find(shape_key); iter != dynamic_size_graph_map_.end()) { | |||
| MS_LOG(INFO) << "This options has been built, read cache."; | |||
| return iter->second; | |||
| } | |||
| auto func_graph = ModelImpl::GetFuncGraph(); | |||
| MS_EXCEPTION_IF_NULL(func_graph); | |||
| auto graph = std::make_shared<Graph>(std::make_shared<Graph::GraphData>(func_graph, ModelType::kMindIR)); | |||
| MS_EXCEPTION_IF_NULL(graph); | |||
| auto graph_cell = std::make_shared<GraphCell>(graph); | |||
| MS_EXCEPTION_IF_NULL(graph_cell); | |||
| auto ret = ModelImpl::Load(graph_cell); | |||
| if (ret != kSuccess) { | |||
| MS_LOG(ERROR) << "Load failed."; | |||
| return nullptr; | |||
| } | |||
| dynamic_size_graph_map_[shape_key] = graph_cell; | |||
| return graph_cell; | |||
| } | |||
| Status MsModel::Build() { | |||
| MS_LOG(INFO) << "Start build model."; | |||
| MS_EXCEPTION_IF_NULL(graph_); | |||
| @@ -34,7 +74,7 @@ Status MsModel::Build(const std::map<std::string, std::string> &) { | |||
| auto graph_cell = std::make_shared<GraphCell>(graph); | |||
| MS_EXCEPTION_IF_NULL(graph_cell); | |||
| auto ret = ModelImpl::Load(graph_cell); | |||
| if (ret != SUCCESS) { | |||
| if (ret != kSuccess) { | |||
| MS_LOG(ERROR) << "Load failed."; | |||
| return ret; | |||
| } | |||
| @@ -42,55 +82,66 @@ Status MsModel::Build(const std::map<std::string, std::string> &) { | |||
| // save result | |||
| graph_cell_ = graph_cell; | |||
| MS_LOG(INFO) << "Build model success."; | |||
| return SUCCESS; | |||
| return kSuccess; | |||
| } | |||
| Status MsModel::Train(const DataSet &, std::map<std::string, Buffer> *) { | |||
| MS_LOG(ERROR) << "Unsupported feature."; | |||
| return FAILED; | |||
| } | |||
| Status MsModel::Resize(const std::vector<MSTensor> &inputs, const std::vector<std::vector<int64_t>> &dims) { | |||
| MS_LOG(INFO) << "Start to resize model"; | |||
| auto origin_inputs = GetInputs(); | |||
| if (inputs.size() != origin_inputs.size()) { | |||
| MS_LOG(ERROR) << "Invalid inputs size " << inputs.size() << " not match model inputs size " << origin_inputs.size(); | |||
| return kMCInvalidInput; | |||
| } | |||
| if (inputs.size() != dims.size()) { | |||
| MS_LOG(ERROR) << "Invalid dims size " << dims.size() << " not match inputs size " << inputs.size(); | |||
| return kMCInvalidInput; | |||
| } | |||
| Status MsModel::Eval(const DataSet &, std::map<std::string, Buffer> *) { | |||
| MS_LOG(ERROR) << "Unsupported feature."; | |||
| return FAILED; | |||
| auto graph_cell = GenerateGraphCell(dims); | |||
| if (graph_cell == nullptr) { | |||
| MS_LOG(ERROR) << "GenerateGraphCell failed."; | |||
| return kMCFailed; | |||
| } | |||
| MS_LOG(INFO) << "Resize model success."; | |||
| graph_cell_ = std::move(graph_cell); | |||
| return kSuccess; | |||
| } | |||
| Status MsModel::Predict(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) { | |||
| Status MsModel::Predict(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) { | |||
| MS_EXCEPTION_IF_NULL(outputs); | |||
| if (graph_ == nullptr) { | |||
| MS_LOG(ERROR) << "Invalid data, graph_ is null."; | |||
| return FAILED; | |||
| return kMCFailed; | |||
| } | |||
| if (graph_cell_ == nullptr) { | |||
| MS_LOG(INFO) << "Model has not been built, it will be built with default options"; | |||
| Status ret = Build({}); | |||
| if (ret != SUCCESS) { | |||
| Status ret = Build(); | |||
| if (ret != kSuccess) { | |||
| MS_LOG(ERROR) << "Build model failed."; | |||
| return FAILED; | |||
| return ret; | |||
| } | |||
| } | |||
| MS_EXCEPTION_IF_NULL(graph_cell_); | |||
| Status ret = graph_cell_->Run(inputs, outputs); | |||
| if (ret != SUCCESS) { | |||
| if (ret != kSuccess) { | |||
| MS_LOG(ERROR) << "Run graph failed."; | |||
| return FAILED; | |||
| return ret; | |||
| } | |||
| return SUCCESS; | |||
| return kSuccess; | |||
| } | |||
| Status MsModel::GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const { | |||
| std::vector<MSTensor> MsModel::GetInputs() { | |||
| MS_EXCEPTION_IF_NULL(graph_cell_); | |||
| return graph_cell_->GetInputsInfo(names, shapes, data_types, mem_sizes); | |||
| return graph_cell_->GetInputs(); | |||
| } | |||
| Status MsModel::GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const { | |||
| std::vector<MSTensor> MsModel::GetOutputs() { | |||
| MS_EXCEPTION_IF_NULL(graph_cell_); | |||
| return graph_cell_->GetOutputsInfo(names, shapes, data_types, mem_sizes); | |||
| return graph_cell_->GetOutputs(); | |||
| } | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| @@ -27,26 +27,24 @@ | |||
| #include "cxx_api/model/model_impl.h" | |||
| namespace mindspore { | |||
| namespace api { | |||
| class MsModel : public ModelImpl { | |||
| public: | |||
| MsModel() {} | |||
| ~MsModel() = default; | |||
| Status Build(const std::map<std::string, std::string> &options_map) override; | |||
| Status Build() override; | |||
| Status Resize(const std::vector<MSTensor> &inputs, const std::vector<std::vector<int64_t>> &dims) override; | |||
| Status Train(const DataSet &dataset, std::map<std::string, Buffer> *outputs) override; | |||
| Status Eval(const DataSet &dataset, std::map<std::string, Buffer> *outputs) override; | |||
| Status Predict(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) override; | |||
| Status Predict(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) override; | |||
| Status GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const override; | |||
| Status GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const override; | |||
| std::vector<MSTensor> GetInputs() override; | |||
| std::vector<MSTensor> GetOutputs() override; | |||
| private: | |||
| std::shared_ptr<GraphCell> GenerateGraphCell(const std::vector<std::vector<int64_t>> &dims); | |||
| std::shared_ptr<GraphCell> graph_cell_; | |||
| std::map<std::string, std::shared_ptr<GraphCell>> dynamic_size_graph_map_; | |||
| }; | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_CCSRC_SESSION_SESSION_BASIC_H | |||
| @@ -1,38 +0,0 @@ | |||
| /** | |||
| * 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 "include/api/ops/ops.h" | |||
| namespace mindspore::api { | |||
| Conv2D::Conv2D(int out_channel, const std::vector<int> &kernel_size, int mode, const std::string &pad_mode, | |||
| const std::vector<int> &pad, const std::vector<int> &stride, const std::vector<int> &dilation, int group) | |||
| : OpCell("Conv2D"), | |||
| out_channel(out_channel), | |||
| kernel_size(kernel_size), | |||
| mode(mode), | |||
| pad_mode(pad_mode), | |||
| pad(pad), | |||
| stride(stride), | |||
| dilation(dilation), | |||
| group(group) {} | |||
| Output Conv2D::operator()(const Input &input1, const Input &input2) const { | |||
| return CellBase::operator()({input1, input2})[0]; | |||
| } | |||
| std::vector<Output> Conv2D::Construct(const std::vector<Input> &inputs) { | |||
| return {Output(shared_from_this(), inputs, 1)}; | |||
| } | |||
| } // namespace mindspore::api | |||
| @@ -14,28 +14,11 @@ | |||
| * limitations under the License. | |||
| */ | |||
| #include "include/api/serialization.h" | |||
| #include <limits.h> | |||
| #include <fstream> | |||
| #include <atomic> | |||
| #include <string> | |||
| #include "cxx_api/graph/graph_data.h" | |||
| #include "utils/utils.h" | |||
| namespace mindspore { | |||
| namespace common { | |||
| const int CACHED_STR_NUM = 1 << 8; | |||
| const int CACHED_STR_MASK = CACHED_STR_NUM - 1; | |||
| std::vector<std::string> STR_HOLDER(CACHED_STR_NUM); | |||
| const char *SafeCStr(const std::string &str) { | |||
| static std::atomic<uint32_t> index{0}; | |||
| uint32_t cur_index = index++; | |||
| cur_index = cur_index & CACHED_STR_MASK; | |||
| STR_HOLDER[cur_index] = str; | |||
| return STR_HOLDER[cur_index].c_str(); | |||
| } | |||
| } // namespace common | |||
| } // namespace mindspore | |||
| namespace mindspore::api { | |||
| static Buffer ReadFile(const std::string &file) { | |||
| Buffer buffer; | |||
| if (file.empty()) { | |||
| @@ -84,6 +67,16 @@ static Buffer ReadFile(const std::string &file) { | |||
| return buffer; | |||
| } | |||
| Graph Serialization::LoadModel(const void *model_data, size_t data_size, ModelType model_type) { | |||
| if (model_type == kMindIR) { | |||
| auto anf_graph = std::make_shared<FuncGraph>(); | |||
| return Graph(std::make_shared<Graph::GraphData>(anf_graph, kMindIR)); | |||
| } else if (model_type == kOM) { | |||
| return Graph(std::make_shared<Graph::GraphData>(Buffer(model_data, data_size), kOM)); | |||
| } | |||
| MS_LOG(EXCEPTION) << "Unsupported ModelType " << model_type; | |||
| } | |||
| Graph Serialization::LoadModel(const std::string &file, ModelType model_type) { | |||
| Buffer data = ReadFile(file); | |||
| if (data.Data() == nullptr) { | |||
| @@ -100,21 +93,21 @@ Graph Serialization::LoadModel(const std::string &file, ModelType model_type) { | |||
| Status Serialization::LoadCheckPoint(const std::string &ckpt_file, std::map<std::string, Buffer> *parameters) { | |||
| MS_LOG(ERROR) << "Unsupported feature."; | |||
| return FAILED; | |||
| return kMEFailed; | |||
| } | |||
| Status Serialization::SetParameters(const std::map<std::string, Buffer> ¶meters, Model *model) { | |||
| MS_LOG(ERROR) << "Unsupported feature."; | |||
| return FAILED; | |||
| return kMEFailed; | |||
| } | |||
| Status Serialization::ExportModel(const Model &model, ModelType model_type, Buffer *model_data) { | |||
| MS_LOG(ERROR) << "Unsupported feature."; | |||
| return FAILED; | |||
| return kMEFailed; | |||
| } | |||
| Status Serialization::ExportModel(const Model &model, ModelType model_type, const std::string &model_file) { | |||
| MS_LOG(ERROR) << "Unsupported feature."; | |||
| return FAILED; | |||
| return kMEFailed; | |||
| } | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| @@ -14,18 +14,22 @@ | |||
| * limitations under the License. | |||
| */ | |||
| #include "include/api/types.h" | |||
| #include <securec.h> | |||
| #include <numeric> | |||
| #include "securec/include/securec.h" | |||
| #include "utils/utils.h" | |||
| namespace mindspore::api { | |||
| const char *kDeviceTypeAscend310 = "Ascend310"; | |||
| const char *kDeviceTypeAscend910 = "Ascend910"; | |||
| class DataImpl { | |||
| namespace mindspore { | |||
| class Buffer::Impl { | |||
| public: | |||
| DataImpl() : data_() {} | |||
| ~DataImpl() = default; | |||
| DataImpl(const void *data, size_t data_len) { SetData(data, data_len); } | |||
| Impl() : data_() {} | |||
| ~Impl() = default; | |||
| Impl(const void *data, size_t data_len) { | |||
| if (data != nullptr) { | |||
| (void)SetData(data, data_len); | |||
| } else { | |||
| ResizeData(data_len); | |||
| } | |||
| } | |||
| const void *Data() const { return data_.data(); } | |||
| void *MutableData() { return data_.data(); } | |||
| @@ -64,132 +68,162 @@ class DataImpl { | |||
| std::vector<uint8_t> data_; | |||
| }; | |||
| class Buffer::Impl : public DataImpl { | |||
| class TensorDefaultImpl : public MSTensor::Impl { | |||
| public: | |||
| Impl() : DataImpl() {} | |||
| ~Impl() = default; | |||
| Impl(const void *data, size_t data_len) : DataImpl(data, data_len) {} | |||
| }; | |||
| TensorDefaultImpl() : buffer_(), name_(), type_(DataType::kTypeUnknown), shape_() {} | |||
| ~TensorDefaultImpl() override = default; | |||
| TensorDefaultImpl(const std::string &name, enum DataType type, const std::vector<int64_t> &shape, const void *data, | |||
| size_t data_len) | |||
| : buffer_(data, data_len), name_(name), type_(type), shape_(shape) {} | |||
| const std::string &Name() const override { return name_; } | |||
| enum DataType DataType() const override { return type_; } | |||
| const std::vector<int64_t> &Shape() const override { return shape_; } | |||
| std::shared_ptr<const void> Data() const override { | |||
| return std::shared_ptr<const void>(buffer_.Data(), [](const void *) {}); | |||
| } | |||
| class Tensor::Impl : public DataImpl { | |||
| public: | |||
| Impl() : DataImpl(), name_(), type_(DataType::kMsUnknown), shape_() {} | |||
| ~Impl() = default; | |||
| Impl(const std::string &name, api::DataType type, const std::vector<int64_t> &shape, const void *data, | |||
| size_t data_len) | |||
| : DataImpl(data, data_len), name_(name), type_(type), shape_(shape) {} | |||
| void *MutableData() override { return buffer_.MutableData(); } | |||
| size_t DataSize() const override { return buffer_.DataSize(); } | |||
| const std::string &Name() const { return name_; } | |||
| void SetName(const std::string &name) { name_ = name; } | |||
| bool IsDevice() const override { return false; } | |||
| api::DataType DataType() const { return type_; } | |||
| void SetDataType(api::DataType type) { type_ = type; } | |||
| std::shared_ptr<Impl> Clone() const override { | |||
| return std::make_shared<TensorDefaultImpl>(name_, type_, shape_, buffer_.Data(), buffer_.DataSize()); | |||
| } | |||
| void SetShape(const std::vector<int64_t> &shape) { shape_ = shape; } | |||
| const std::vector<int64_t> &Shape() const { return shape_; } | |||
| private: | |||
| Buffer buffer_; | |||
| std::string name_; | |||
| enum DataType type_; | |||
| std::vector<int64_t> shape_; | |||
| }; | |||
| int64_t ElementNum() const { | |||
| std::vector<int64_t> shapex = Shape(); | |||
| return std::accumulate(shapex.begin(), shapex.end(), 1LL, std::multiplies<int64_t>()); | |||
| class TensorReferenceImpl : public MSTensor::Impl { | |||
| public: | |||
| TensorReferenceImpl() : data_(nullptr), data_size_(0), name_(), type_(DataType::kTypeUnknown), shape_() {} | |||
| ~TensorReferenceImpl() override = default; | |||
| TensorReferenceImpl(const std::string &name, enum DataType type, const std::vector<int64_t> &shape, const void *data, | |||
| size_t data_len) | |||
| : data_(data), data_size_(data_len), name_(name), type_(type), shape_(shape) {} | |||
| const std::string &Name() const override { return name_; } | |||
| enum DataType DataType() const override { return type_; } | |||
| const std::vector<int64_t> &Shape() const override { return shape_; } | |||
| std::shared_ptr<const void> Data() const override { | |||
| return std::shared_ptr<const void>(data_, [](const void *) {}); | |||
| } | |||
| static int GetTypeSize(api::DataType type) { | |||
| static const std::map<api::DataType, size_t> type_size_map = { | |||
| {kMsBool, sizeof(bool)}, {kMsFloat64, sizeof(double)}, {kMsInt8, sizeof(int8_t)}, | |||
| {kMsUint8, sizeof(uint8_t)}, {kMsInt16, sizeof(int16_t)}, {kMsUint16, sizeof(uint16_t)}, | |||
| {kMsInt32, sizeof(int32_t)}, {kMsUint32, sizeof(uint32_t)}, {kMsInt64, sizeof(int64_t)}, | |||
| {kMsUint64, sizeof(uint64_t)}, {kMsFloat16, sizeof(uint16_t)}, {kMsFloat32, sizeof(float)}, | |||
| }; | |||
| auto it = type_size_map.find(type); | |||
| if (it != type_size_map.end()) { | |||
| return it->second; | |||
| } | |||
| void *MutableData() override { return const_cast<void *>(data_); } | |||
| size_t DataSize() const override { return data_size_; } | |||
| bool IsDevice() const override { return false; } | |||
| MS_LOG(WARNING) << "Cannot find data type " << type; | |||
| return 0; | |||
| std::shared_ptr<Impl> Clone() const override { | |||
| return std::make_shared<TensorReferenceImpl>(name_, type_, shape_, data_, data_size_); | |||
| } | |||
| private: | |||
| protected: | |||
| const void *data_; | |||
| size_t data_size_; | |||
| std::string name_; | |||
| api::DataType type_; | |||
| enum DataType type_; | |||
| std::vector<int64_t> shape_; | |||
| }; | |||
| Tensor::Tensor() : impl_(std::make_shared<Impl>()) {} | |||
| Tensor::Tensor(const std::string &name, api::DataType type, const std::vector<int64_t> &shape, const void *data, | |||
| size_t data_len) | |||
| : impl_(std::make_shared<Impl>(name, type, shape, data, data_len)) {} | |||
| Tensor::~Tensor() = default; | |||
| Tensor Tensor::Clone() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| Tensor ret; | |||
| ret.impl_ = std::make_shared<Impl>(*impl_); | |||
| return ret; | |||
| MSTensor MSTensor::CreateTensor(const std::string &name, enum DataType type, const std::vector<int64_t> &shape, | |||
| const void *data, size_t data_len) noexcept { | |||
| try { | |||
| std::shared_ptr<Impl> impl = std::make_shared<TensorDefaultImpl>(name, type, shape, data, data_len); | |||
| return MSTensor(impl); | |||
| } catch (const std::bad_alloc &) { | |||
| MS_LOG(ERROR) << "Malloc memory failed."; | |||
| return MSTensor(nullptr); | |||
| } catch (...) { | |||
| MS_LOG(ERROR) << "Unknown error occurred."; | |||
| return MSTensor(nullptr); | |||
| } | |||
| } | |||
| const std::string &Tensor::Name() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->Name(); | |||
| MSTensor MSTensor::CreateRefTensor(const std::string &name, enum DataType type, const std::vector<int64_t> &shape, | |||
| const void *data, size_t data_len) noexcept { | |||
| try { | |||
| std::shared_ptr<Impl> impl = std::make_shared<TensorReferenceImpl>(name, type, shape, data, data_len); | |||
| return MSTensor(impl); | |||
| } catch (const std::bad_alloc &) { | |||
| MS_LOG(ERROR) << "Malloc memory failed."; | |||
| return MSTensor(nullptr); | |||
| } catch (...) { | |||
| MS_LOG(ERROR) << "Unknown error occurred."; | |||
| return MSTensor(nullptr); | |||
| } | |||
| } | |||
| void Tensor::SetName(const std::string &name) { | |||
| MSTensor::MSTensor() : impl_(std::make_shared<TensorDefaultImpl>()) {} | |||
| MSTensor::MSTensor(std::nullptr_t) : impl_(nullptr) {} | |||
| MSTensor::MSTensor(const std::shared_ptr<Impl> &impl) : impl_(impl) { MS_EXCEPTION_IF_NULL(impl); } | |||
| MSTensor::MSTensor(const std::string &name, enum DataType type, const std::vector<int64_t> &shape, const void *data, | |||
| size_t data_len) | |||
| : impl_(std::make_shared<TensorDefaultImpl>(name, type, shape, data, data_len)) {} | |||
| MSTensor::~MSTensor() = default; | |||
| bool MSTensor::operator==(std::nullptr_t) const { return impl_ == nullptr; } | |||
| MSTensor MSTensor::Clone() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| impl_->SetName(name); | |||
| MSTensor ret; | |||
| ret.impl_ = impl_->Clone(); | |||
| return ret; | |||
| } | |||
| DataType Tensor::DataType() const { | |||
| const std::string &MSTensor::Name() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->DataType(); | |||
| return impl_->Name(); | |||
| } | |||
| void Tensor::SetDataType(api::DataType type) { | |||
| enum DataType MSTensor::DataType() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| impl_->SetDataType(type); | |||
| return impl_->DataType(); | |||
| } | |||
| const std::vector<int64_t> &Tensor::Shape() const { | |||
| const std::vector<int64_t> &MSTensor::Shape() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->Shape(); | |||
| } | |||
| void Tensor::SetShape(const std::vector<int64_t> &shape) { | |||
| int64_t MSTensor::ElementNum() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| impl_->SetShape(shape); | |||
| const auto &shape = impl_->Shape(); | |||
| if (shape.empty()) { | |||
| // element number of scalar is 1 | |||
| return 1; | |||
| } | |||
| return std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<int64_t>()); | |||
| } | |||
| const void *Tensor::Data() const { | |||
| std::shared_ptr<const void> MSTensor::Data() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->Data(); | |||
| } | |||
| void *Tensor::MutableData() { | |||
| void *MSTensor::MutableData() { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->MutableData(); | |||
| } | |||
| size_t Tensor::DataSize() const { | |||
| size_t MSTensor::DataSize() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->DataSize(); | |||
| } | |||
| bool Tensor::ResizeData(size_t data_len) { | |||
| bool MSTensor::IsDevice() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->ResizeData(data_len); | |||
| return impl_->IsDevice(); | |||
| } | |||
| bool Tensor::SetData(const void *data, size_t data_len) { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->SetData(data, data_len); | |||
| } | |||
| int64_t Tensor::ElementNum() const { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->ElementNum(); | |||
| } | |||
| int Tensor::GetTypeSize(api::DataType type) { return Impl::GetTypeSize(type); } | |||
| Buffer::Buffer() : impl_(std::make_shared<Impl>()) {} | |||
| Buffer::Buffer(const void *data, size_t data_len) : impl_(std::make_shared<Impl>(data, data_len)) {} | |||
| Buffer::~Buffer() = default; | |||
| @@ -225,4 +259,4 @@ bool Buffer::SetData(const void *data, size_t data_len) { | |||
| MS_EXCEPTION_IF_NULL(impl_); | |||
| return impl_->SetData(data, data_len); | |||
| } | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| @@ -15,11 +15,12 @@ | |||
| */ | |||
| #include "stub/graph_impl_stub.h" | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| GraphImplStubAdd::GraphImplStubAdd() { Init({2, 2}); } | |||
| GraphImplStubAdd::GraphImplStubAdd(const std::vector<int64_t> &add_shape) { Init(add_shape); } | |||
| GraphImplStubAdd::~GraphImplStubAdd() {} | |||
| void GraphImplStubAdd::Init(const std::vector<int64_t> &add_shape) { | |||
| auto element_cnt = [add_shape]() -> size_t { | |||
| size_t element_num = 1; | |||
| @@ -32,62 +33,43 @@ void GraphImplStubAdd::Init(const std::vector<int64_t> &add_shape) { | |||
| return element_num; | |||
| }; | |||
| auto ele_size = element_cnt() * sizeof(float); | |||
| MSTensor tensor_x1 = MSTensor("x1", mindspore::DataType::kNumberTypeFloat32, add_shape, nullptr, ele_size); | |||
| MSTensor tensor_x2 = MSTensor("x2", mindspore::DataType::kNumberTypeFloat32, add_shape, nullptr, ele_size); | |||
| input_shapes_.push_back(add_shape); | |||
| input_shapes_.push_back(add_shape); | |||
| input_data_types_.push_back(api::kMsFloat32); | |||
| input_data_types_.push_back(api::kMsFloat32); | |||
| input_names_.emplace_back("x1"); | |||
| input_names_.emplace_back("x2"); | |||
| input_mem_sizes_.push_back(ele_size); | |||
| input_mem_sizes_.push_back(ele_size); | |||
| MSTensor tensor_y = MSTensor("y", mindspore::DataType::kNumberTypeFloat32, add_shape, nullptr, ele_size); | |||
| output_shapes_.push_back(add_shape); | |||
| output_data_types_.push_back(api::kMsFloat32); | |||
| output_names_.emplace_back("y"); | |||
| output_mem_sizes_.push_back(ele_size); | |||
| inputs_.push_back(tensor_x1); | |||
| inputs_.push_back(tensor_x2); | |||
| outputs_.push_back(tensor_y); | |||
| } | |||
| Status GraphImplStubAdd::Run(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) { | |||
| if (inputs.size() != input_names_.size()) { | |||
| return FAILED; | |||
| Status GraphImplStubAdd::Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) { | |||
| if (inputs.size() != inputs_.size()) { | |||
| return mindspore::kCoreFailed; | |||
| } | |||
| for (size_t i = 0; i < inputs.size(); i++) { | |||
| if (inputs[i].DataSize() != input_mem_sizes_[i]) { | |||
| return FAILED; | |||
| if (inputs[i].DataSize() != inputs_[i].DataSize()) { | |||
| return mindspore::kCoreFailed; | |||
| } | |||
| if (input_mem_sizes_[i] != 0 && inputs[i].Data() == nullptr) { | |||
| return FAILED; | |||
| if (inputs_[i].DataSize() != 0 && inputs[i].Data() == nullptr) { | |||
| return mindspore::kCoreFailed; | |||
| } | |||
| } | |||
| auto x1 = reinterpret_cast<const float *>(inputs[0].Data()); | |||
| auto x2 = reinterpret_cast<const float *>(inputs[1].Data()); | |||
| Buffer output; | |||
| output.ResizeData(output_mem_sizes_[0]); | |||
| auto x1 = reinterpret_cast<const float *>(inputs[0].Data().get()); | |||
| auto x2 = reinterpret_cast<const float *>(inputs[1].Data().get()); | |||
| MSTensor output = outputs_[0].Clone(); | |||
| auto y = reinterpret_cast<float *>(output.MutableData()); | |||
| for (size_t i = 0; i < output_mem_sizes_[0] / sizeof(float); i++) { | |||
| for (size_t i = 0; i < outputs_[0].DataSize() / sizeof(float); i++) { | |||
| y[i] = x1[i] + x2[i]; | |||
| } | |||
| outputs->push_back(output); | |||
| return SUCCESS; | |||
| return mindspore::kSuccess; | |||
| } | |||
| Status GraphImplStubAdd::Load() { return SUCCESS; } | |||
| Status GraphImplStubAdd::GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) { | |||
| *names = input_names_; | |||
| *shapes = input_shapes_; | |||
| *data_types = input_data_types_; | |||
| *mem_sizes = input_mem_sizes_; | |||
| return SUCCESS; | |||
| } | |||
| Status GraphImplStubAdd::GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) { | |||
| *names = output_names_; | |||
| *shapes = output_shapes_; | |||
| *data_types = output_data_types_; | |||
| *mem_sizes = output_mem_sizes_; | |||
| return SUCCESS; | |||
| } | |||
| Status GraphImplStubAdd::Load() { return kSuccess; } | |||
| std::vector<MSTensor> GraphImplStubAdd::GetInputs() { return inputs_; } | |||
| std::vector<MSTensor> GraphImplStubAdd::GetOutputs() { return outputs_; } | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| @@ -28,34 +28,26 @@ | |||
| #include "cxx_api/graph/graph_impl.h" | |||
| #include "cxx_api/model/model_impl.h" | |||
| namespace mindspore::api { | |||
| namespace mindspore { | |||
| class GraphImplStubAdd : public GraphCell::GraphImpl { | |||
| public: | |||
| GraphImplStubAdd(); | |||
| explicit GraphImplStubAdd(const std::vector<int64_t> &add_shape); | |||
| ~GraphImplStubAdd() override; | |||
| Status Run(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) override; | |||
| Status Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) override; | |||
| Status Load() override; | |||
| Status GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) override; | |||
| Status GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) override; | |||
| private: | |||
| std::vector<std::string> input_names_; | |||
| std::vector<std::vector<int64_t>> input_shapes_; | |||
| std::vector<DataType> input_data_types_; | |||
| std::vector<size_t> input_mem_sizes_; | |||
| std::vector<MSTensor> GetInputs() override; | |||
| std::vector<MSTensor> GetOutputs() override; | |||
| std::vector<std::string> output_names_; | |||
| std::vector<std::vector<int64_t>> output_shapes_; | |||
| std::vector<DataType> output_data_types_; | |||
| std::vector<size_t> output_mem_sizes_; | |||
| private: | |||
| std::vector<MSTensor> inputs_; | |||
| std::vector<MSTensor> outputs_; | |||
| void Init(const std::vector<int64_t> &add_shape); | |||
| }; | |||
| } // namespace mindspore::api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_SERVING_GRAPH_IMPL_STUB_H | |||
| @@ -24,7 +24,6 @@ | |||
| #include "include/api/graph.h" | |||
| namespace mindspore { | |||
| namespace api { | |||
| class InputAndOutput; | |||
| using Input = InputAndOutput; | |||
| using Output = InputAndOutput; | |||
| @@ -35,7 +34,7 @@ class MS_API CellBase { | |||
| virtual ~CellBase() = default; | |||
| virtual std::vector<Output> Construct(const std::vector<Input> &inputs) { return {}; } | |||
| virtual std::shared_ptr<CellBase> Clone() const = 0; | |||
| virtual Status Run(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) { return SUCCESS; } | |||
| virtual Status Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) { return kSuccess; } | |||
| std::vector<Output> operator()(const std::vector<Input> &inputs) const; | |||
| }; | |||
| @@ -57,16 +56,16 @@ class MS_API ParameterCell final : public Cell<ParameterCell> { | |||
| ParameterCell(ParameterCell &&); | |||
| ParameterCell &operator=(ParameterCell &&); | |||
| explicit ParameterCell(const Tensor &); | |||
| ParameterCell &operator=(const Tensor &); | |||
| explicit ParameterCell(const MSTensor &); | |||
| ParameterCell &operator=(const MSTensor &); | |||
| explicit ParameterCell(Tensor &&); | |||
| ParameterCell &operator=(Tensor &&); | |||
| explicit ParameterCell(MSTensor &&); | |||
| ParameterCell &operator=(MSTensor &&); | |||
| Tensor GetTensor() const { return tensor_; } | |||
| MSTensor GetTensor() const { return tensor_; } | |||
| private: | |||
| Tensor tensor_; | |||
| MSTensor tensor_; | |||
| }; | |||
| class MS_API OpCellBase : public CellBase { | |||
| @@ -99,11 +98,9 @@ class MS_API GraphCell final : public Cell<GraphCell> { | |||
| explicit GraphCell(const std::shared_ptr<Graph> &); | |||
| const std::shared_ptr<Graph> &GetGraph() const { return graph_; } | |||
| Status Run(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs) override; | |||
| Status GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const; | |||
| Status GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const; | |||
| Status Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) override; | |||
| std::vector<MSTensor> GetInputs(); | |||
| std::vector<MSTensor> GetOutputs(); | |||
| private: | |||
| friend class ModelImpl; | |||
| @@ -119,8 +116,8 @@ class MS_API InputAndOutput { | |||
| ~InputAndOutput() = default; | |||
| // no explicit | |||
| InputAndOutput(const Tensor &); // NOLINT(runtime/explicit) | |||
| InputAndOutput(Tensor &&); // NOLINT(runtime/explicit) | |||
| InputAndOutput(const MSTensor &); // NOLINT(runtime/explicit) | |||
| InputAndOutput(MSTensor &&); // NOLINT(runtime/explicit) | |||
| InputAndOutput(const std::shared_ptr<CellBase> &, const std::vector<InputAndOutput> &, int32_t index); | |||
| @@ -132,6 +129,5 @@ class MS_API InputAndOutput { | |||
| std::vector<InputAndOutput> prev_; | |||
| int32_t index_; | |||
| }; | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_INCLUDE_API_CELL_H | |||
| @@ -16,26 +16,49 @@ | |||
| #ifndef MINDSPORE_INCLUDE_API_CONTEXT_H | |||
| #define MINDSPORE_INCLUDE_API_CONTEXT_H | |||
| #include <map> | |||
| #include <any> | |||
| #include <string> | |||
| #include <memory> | |||
| #include "include/api/types.h" | |||
| namespace mindspore { | |||
| namespace api { | |||
| class MS_API Context { | |||
| public: | |||
| static Context &Instance(); | |||
| const std::string &GetDeviceTarget() const; | |||
| Context &SetDeviceTarget(const std::string &device_target); | |||
| uint32_t GetDeviceID() const; | |||
| Context &SetDeviceID(uint32_t device_id); | |||
| private: | |||
| Context(); | |||
| ~Context(); | |||
| class ContextImpl; | |||
| std::shared_ptr<ContextImpl> impl_; | |||
| constexpr auto kDeviceTypeAscend310 = "Ascend310"; | |||
| constexpr auto kDeviceTypeAscend910 = "Ascend910"; | |||
| struct MS_API Context { | |||
| virtual ~Context() = default; | |||
| std::map<std::string, std::any> params; | |||
| }; | |||
| struct MS_API GlobalContext : public Context { | |||
| static std::shared_ptr<Context> GetGlobalContext(); | |||
| static void SetGlobalDeviceTarget(const std::string &device_target); | |||
| static std::string GetGlobalDeviceTarget(); | |||
| static void SetGlobalDeviceID(const uint32_t &device_id); | |||
| static uint32_t GetGlobalDeviceID(); | |||
| }; | |||
| struct MS_API ModelContext : public Context { | |||
| static void SetInsertOpConfigPath(const std::shared_ptr<Context> &context, const std::string &cfg_path); | |||
| static std::string GetInsertOpConfigPath(const std::shared_ptr<Context> &context); | |||
| static void SetInputFormat(const std::shared_ptr<Context> &context, const std::string &format); | |||
| static std::string GetInputFormat(const std::shared_ptr<Context> &context); | |||
| static void SetInputShape(const std::shared_ptr<Context> &context, const std::string &shape); | |||
| static std::string GetInputShape(const std::shared_ptr<Context> &context); | |||
| static void SetOutputType(const std::shared_ptr<Context> &context, enum DataType output_type); | |||
| static enum DataType GetOutputType(const std::shared_ptr<Context> &context); | |||
| static void SetPrecisionMode(const std::shared_ptr<Context> &context, const std::string &precision_mode); | |||
| static std::string GetPrecisionMode(const std::shared_ptr<Context> &context); | |||
| static void SetOpSelectImplMode(const std::shared_ptr<Context> &context, const std::string &op_select_impl_mode); | |||
| static std::string GetOpSelectImplMode(const std::shared_ptr<Context> &context); | |||
| }; | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_INCLUDE_API_CONTEXT_H | |||
| @@ -0,0 +1,46 @@ | |||
| /** | |||
| * This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/). | |||
| * | |||
| * Copyright 2019-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_INCLUDE_API_DATA_TYPE_H_ | |||
| #define MINDSPORE_INCLUDE_API_DATA_TYPE_H_ | |||
| namespace mindspore { | |||
| enum class DataType : int { | |||
| kTypeUnknown = 0, | |||
| kObjectTypeString = 12, | |||
| kObjectTypeList = 13, | |||
| kObjectTypeTuple = 14, | |||
| kObjectTypeTensorType = 17, | |||
| kNumberTypeBool = 30, | |||
| kNumberTypeInt8 = 32, | |||
| kNumberTypeInt16 = 33, | |||
| kNumberTypeInt32 = 34, | |||
| kNumberTypeInt64 = 35, | |||
| kNumberTypeUInt8 = 37, | |||
| kNumberTypeUInt16 = 38, | |||
| kNumberTypeUInt32 = 39, | |||
| kNumberTypeUInt64 = 40, | |||
| kNumberTypeFloat16 = 42, | |||
| kNumberTypeFloat32 = 43, | |||
| kNumberTypeFloat64 = 44, | |||
| kNumberTypeEnd = 46, | |||
| // add new enum here | |||
| kInvalidType = INT32_MAX, | |||
| }; | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_INCLUDE_API_DATA_TYPE_H_ | |||
| @@ -16,6 +16,7 @@ | |||
| #ifndef MINDSPORE_INCLUDE_API_GRAPH_H | |||
| #define MINDSPORE_INCLUDE_API_GRAPH_H | |||
| #include <cstddef> | |||
| #include <string> | |||
| #include <vector> | |||
| #include <map> | |||
| @@ -24,26 +25,21 @@ | |||
| #include "include/api/types.h" | |||
| namespace mindspore { | |||
| namespace api { | |||
| class MS_API Graph { | |||
| public: | |||
| class GraphData; | |||
| explicit Graph(const std::shared_ptr<GraphData> &graph_data); | |||
| explicit Graph(std::shared_ptr<GraphData> &&graph_data); | |||
| explicit Graph(std::nullptr_t); | |||
| ~Graph(); | |||
| enum ModelType ModelType() const; | |||
| bool operator==(std::nullptr_t) const; | |||
| private: | |||
| friend class GraphCell; | |||
| friend class ModelImpl; | |||
| std::shared_ptr<GraphData> graph_data_; | |||
| }; | |||
| class FuncGraph {}; | |||
| using FuncGraphPtr = std::shared_ptr<FuncGraph>; | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_INCLUDE_API_GRAPH_H | |||
| @@ -20,41 +20,36 @@ | |||
| #include <vector> | |||
| #include <map> | |||
| #include <memory> | |||
| #include <utility> | |||
| #include "include/api/status.h" | |||
| #include "include/api/types.h" | |||
| #include "include/api/graph.h" | |||
| #include "include/api/cell.h" | |||
| namespace mindspore { | |||
| namespace api { | |||
| class ModelImpl; | |||
| // todo: minddata c++ interface | |||
| class DataSet {}; | |||
| struct Context; | |||
| class MS_API Model { | |||
| public: | |||
| explicit Model(const std::vector<Output> &network); | |||
| explicit Model(const GraphCell &graph); | |||
| explicit Model(const std::vector<Output> &network, const std::shared_ptr<Context> &model_context = nullptr); | |||
| explicit Model(const GraphCell &graph, const std::shared_ptr<Context> &model_context = nullptr); | |||
| ~Model(); | |||
| Model(const Model &) = delete; | |||
| void operator=(const Model &) = delete; | |||
| Status Build(const std::map<std::string, std::string> &options); | |||
| Status Build(); | |||
| Status Resize(const std::vector<MSTensor> &inputs, const std::vector<std::vector<int64_t>> &dims); | |||
| Status Train(const DataSet &dataset, bool data_sink, std::map<std::string, Buffer> *outputs); | |||
| Status Eval(const DataSet &dataset, bool data_sink, std::map<std::string, Buffer> *outputs); | |||
| Status Predict(const std::vector<Buffer> &inputs, std::vector<Buffer> *outputs); | |||
| Status Predict(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs); | |||
| Status GetInputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const; | |||
| Status GetOutputsInfo(std::vector<std::string> *names, std::vector<std::vector<int64_t>> *shapes, | |||
| std::vector<DataType> *data_types, std::vector<size_t> *mem_sizes) const; | |||
| std::vector<MSTensor> GetInputs(); | |||
| std::vector<MSTensor> GetOutputs(); | |||
| static bool CheckModelSupport(const std::string &device_type, ModelType model_type); | |||
| private: | |||
| std::shared_ptr<ModelImpl> impl_; | |||
| }; | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_INCLUDE_API_MODEL_H | |||
| @@ -1,50 +0,0 @@ | |||
| /** | |||
| * 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_INCLUDE_API_OPS_OPS_H | |||
| #define MINDSPORE_INCLUDE_API_OPS_OPS_H | |||
| #include <string> | |||
| #include <vector> | |||
| #include <map> | |||
| #include <memory> | |||
| #include "include/api/status.h" | |||
| #include "include/api/types.h" | |||
| #include "include/api/cell.h" | |||
| namespace mindspore { | |||
| namespace api { | |||
| struct MS_API Conv2D : public OpCell<Conv2D> { | |||
| Conv2D() : OpCell("Conv2D") {} | |||
| ~Conv2D() override = default; | |||
| std::vector<Output> Construct(const std::vector<Input> &inputs) override; | |||
| Conv2D(int out_channel, const std::vector<int> &kernel_size, int mode = 1, const std::string &pad_mode = "valid", | |||
| const std::vector<int> &pad = {0, 0, 0, 0}, const std::vector<int> &stride = {1, 1, 1, 1}, | |||
| const std::vector<int> &dilation = {1, 1, 1, 1}, int group = 1); | |||
| Output operator()(const Input &, const Input &) const; | |||
| int out_channel; | |||
| std::vector<int> kernel_size; | |||
| int mode = 1; | |||
| std::string pad_mode = "valid"; | |||
| std::vector<int> pad = {0, 0, 0, 0}; | |||
| std::vector<int> stride = {1, 1, 1, 1}; | |||
| std::vector<int> dilation = {1, 1, 1, 1}; | |||
| int group = 1; | |||
| }; | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_INCLUDE_API_OPS_OPS_H | |||
| @@ -26,15 +26,14 @@ | |||
| #include "include/api/graph.h" | |||
| namespace mindspore { | |||
| namespace api { | |||
| class MS_API Serialization { | |||
| public: | |||
| static Graph LoadModel(const void *model_data, size_t data_size, ModelType model_type); | |||
| static Graph LoadModel(const std::string &file, ModelType model_type); | |||
| static Status LoadCheckPoint(const std::string &ckpt_file, std::map<std::string, Buffer> *parameters); | |||
| static Status SetParameters(const std::map<std::string, Buffer> ¶meters, Model *model); | |||
| static Status ExportModel(const Model &model, ModelType model_type, Buffer *model_data); | |||
| static Status ExportModel(const Model &model, ModelType model_type, const std::string &model_file); | |||
| }; | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_INCLUDE_API_SERIALIZATION_H | |||
| @@ -17,37 +17,122 @@ | |||
| #define MINDSPORE_INCLUDE_API_STATUS_H | |||
| #include <string> | |||
| #include <ostream> | |||
| #include <climits> | |||
| namespace mindspore { | |||
| namespace api { | |||
| enum StatusCode { | |||
| SUCCESS = 0, | |||
| FAILED, | |||
| INVALID_INPUTS, | |||
| // insert new status code here | |||
| UNKNOWN = 0xFFFFFFFF | |||
| enum CompCode : uint32_t { | |||
| kCore = 0x00000000u, | |||
| kMD = 0x10000000u, | |||
| kME = 0x20000000u, | |||
| kMC = 0x30000000u, | |||
| kLite = 0xF0000000u, | |||
| }; | |||
| enum StatusCode : uint32_t { | |||
| kSuccess = 0, | |||
| // Core | |||
| kCoreFailed = kCore | 0x1, | |||
| // MD | |||
| kMDOutOfMemory = kMD | 1, | |||
| kMDShapeMisMatch = kMD | 2, | |||
| kMDInterrupted = kMD | 3, | |||
| kMDNoSpace = kMD | 4, | |||
| kMDPyFuncException = kMD | 5, | |||
| kMDDuplicateKey = kMD | 6, | |||
| kMDPythonInterpreterFailure = kMD | 7, | |||
| kMDTDTPushFailure = kMD | 8, | |||
| kMDFileNotExist = kMD | 9, | |||
| kMDProfilingError = kMD | 10, | |||
| kMDBoundingBoxOutOfBounds = kMD | 11, | |||
| kMDBoundingBoxInvalidShape = kMD | 12, | |||
| kMDSyntaxError = kMD | 13, | |||
| kMDTimeOut = kMD | 14, | |||
| kMDBuddySpaceFull = kMD | 15, | |||
| kMDNetWorkError = kMD | 16, | |||
| kMDNotImplementedYet = kMD | 17, | |||
| // Make this error code the last one. Add new error code above it. | |||
| kMDUnexpectedError = kMD | 127, | |||
| // ME | |||
| kMEFailed = kME | 0x1, | |||
| kMEInvalidInput = kME | 0x2, | |||
| // MC | |||
| kMCFailed = kMC | 0x1, | |||
| kMCDeviceError = kMC | 0x2, | |||
| kMCInvalidInput = kMC | 0x3, | |||
| kMCInvalidArgs = kMC | 0x4, | |||
| // Lite // Common error code, range: [-1, -100) | |||
| kLiteError = kLite | (0x0FFFFFFF & -1), /**< Common error code. */ | |||
| kLiteNullptr = kLite | (0x0FFFFFFF & -2), /**< NULL pointer returned.*/ | |||
| kLiteParamInvalid = kLite | (0x0FFFFFFF & -3), /**< Invalid parameter.*/ | |||
| kLiteNoChange = kLite | (0x0FFFFFFF & -4), /**< No change. */ | |||
| kLiteSuccessExit = kLite | (0x0FFFFFFF & -5), /**< No error but exit. */ | |||
| kLiteMemoryFailed = kLite | (0x0FFFFFFF & -6), /**< Fail to create memory. */ | |||
| kLiteNotSupport = kLite | (0x0FFFFFFF & -7), /**< Fail to support. */ | |||
| kLiteThreadPoolError = kLite | (0x0FFFFFFF & -8), /**< Error occur in thread pool. */ | |||
| // Executor error code, range: [-100,-200) | |||
| kLiteOutOfTensorRange = kLite | (0x0FFFFFFF & -100), /**< Failed to check range. */ | |||
| kLiteInputTensorError = kLite | (0x0FFFFFFF & -101), /**< Failed to check input tensor. */ | |||
| kLiteReentrantError = kLite | (0x0FFFFFFF & -102), /**< Exist executor running. */ | |||
| // Graph error code, range: [-200,-300) | |||
| kLiteGraphFileError = kLite | (0x0FFFFFFF & -200), /**< Failed to verify graph file. */ | |||
| // Node error code, range: [-300,-400) | |||
| kLiteNotFindOp = kLite | (0x0FFFFFFF & -300), /**< Failed to find operator. */ | |||
| kLiteInvalidOpName = kLite | (0x0FFFFFFF & -301), /**< Invalid operator name. */ | |||
| kLiteInvalidOpAttr = kLite | (0x0FFFFFFF & -302), /**< Invalid operator attr. */ | |||
| kLiteOpExecuteFailure = kLite | (0x0FFFFFFF & -303), /**< Failed to execution operator. */ | |||
| // Tensor error code, range: [-400,-500) | |||
| kLiteFormatError = kLite | (0x0FFFFFFF & -400), /**< Failed to checking tensor format. */ | |||
| // InferShape error code, range: [-500,-600) | |||
| kLiteInferError = kLite | (0x0FFFFFFF & -500), /**< Failed to infer shape. */ | |||
| kLiteInferInvalid = kLite | (0x0FFFFFFF & -501), /**< Invalid infer shape before runtime. */ | |||
| // User input param error code, range: [-600, 700) | |||
| kLiteInputParamInvalid = kLite | (0x0FFFFFFF & -600), /**< Invalid input param by user. */ | |||
| }; | |||
| class Status { | |||
| public: | |||
| Status() : status_code_(FAILED) {} | |||
| Status() : status_code_(kSuccess) {} | |||
| Status(enum StatusCode status_code, const std::string &status_msg = "") // NOLINT(runtime/explicit) | |||
| : status_code_(status_code), status_msg_(status_msg) {} | |||
| Status(const StatusCode code, int line_of_code, const char *file_name, const std::string &extra = ""); | |||
| ~Status() = default; | |||
| bool IsSuccess() const { return status_code_ == SUCCESS; } | |||
| enum StatusCode StatusCode() const { return status_code_; } | |||
| std::string StatusMessage() const { return status_msg_; } | |||
| const std::string &ToString() const { return status_msg_; } | |||
| friend std::ostream &operator<<(std::ostream &os, const Status &s); | |||
| bool operator==(const Status &other) const { return status_code_ == other.status_code_; } | |||
| bool operator==(enum StatusCode other_code) const { return status_code_ == other_code; } | |||
| bool operator!=(const Status &other) const { return status_code_ != other.status_code_; } | |||
| bool operator!=(enum StatusCode other_code) const { return status_code_ != other_code; } | |||
| operator bool() const = delete; | |||
| explicit operator bool() const { return (status_code_ == kSuccess); } | |||
| explicit operator int() const { return static_cast<int>(status_code_); } | |||
| static Status OK() { return Status(StatusCode::kSuccess); } | |||
| bool IsOk() const { return (StatusCode() == StatusCode::kSuccess); } | |||
| bool IsError() const { return !IsOk(); } | |||
| static std::string CodeAsString(enum StatusCode c); | |||
| private: | |||
| enum StatusCode status_code_; | |||
| std::string status_msg_; | |||
| }; | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_INCLUDE_API_STATUS_H | |||
| @@ -16,22 +16,33 @@ | |||
| #ifndef MINDSPORE_INCLUDE_API_TYPES_H | |||
| #define MINDSPORE_INCLUDE_API_TYPES_H | |||
| #include <cstddef> | |||
| #include <string> | |||
| #include <vector> | |||
| #include <memory> | |||
| #include "common/status.h" | |||
| #include "include/api/data_type.h" | |||
| // refer to https://gcc.gnu.org/wiki/Visibility | |||
| #if defined _WIN32 || defined __CYGWIN__ | |||
| #ifdef BUILDING_DLL | |||
| #ifdef __GNUC__ | |||
| #define MS_API __attribute__((dllexport)) | |||
| #else | |||
| #define MS_API __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. | |||
| #endif | |||
| #else | |||
| #ifdef __GNUC__ | |||
| #define MS_API __attribute__((dllimport)) | |||
| #else | |||
| #define MS_API __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. | |||
| #endif | |||
| #endif | |||
| #else | |||
| #define MS_API __attribute__((visibility("default"))) | |||
| #define MS_LOG MSI_LOG | |||
| #define MS_LOG_ERRROR MSI_LOG_ERRROR | |||
| #define MS_LOG_WARNING MSI_LOG_WARNING | |||
| #define MS_LOG_INFO MSI_LOG_INFO | |||
| #define MS_EXCEPTION_IF_NULL MSI_EXCEPTION_IF_NULL | |||
| #endif | |||
| namespace mindspore { | |||
| namespace api { | |||
| enum ModelType { | |||
| enum ModelType : uint32_t { | |||
| kMindIR = 0, | |||
| kAIR = 1, | |||
| kOM = 2, | |||
| @@ -40,55 +51,59 @@ enum ModelType { | |||
| kUnknownType = 0xFFFFFFFF | |||
| }; | |||
| enum DataType { | |||
| kMsUnknown = 0, | |||
| kMsBool = 1, | |||
| kMsInt8 = 2, | |||
| kMsInt16 = 3, | |||
| kMsInt32 = 4, | |||
| kMsInt64 = 5, | |||
| kMsUint8 = 6, | |||
| kMsUint16 = 7, | |||
| kMsUint32 = 8, | |||
| kMsUint64 = 9, | |||
| kMsFloat16 = 10, | |||
| kMsFloat32 = 11, | |||
| kMsFloat64 = 12, | |||
| // insert new data type here | |||
| kInvalidDataType = 0xFFFFFFFF | |||
| }; | |||
| class MS_API Tensor { | |||
| class MS_API MSTensor { | |||
| public: | |||
| Tensor(); | |||
| Tensor(const std::string &name, DataType type, const std::vector<int64_t> &shape, const void *data, size_t data_len); | |||
| ~Tensor(); | |||
| class Impl; | |||
| const std::string &Name() const; | |||
| void SetName(const std::string &name); | |||
| static MSTensor CreateTensor(const std::string &name, DataType type, const std::vector<int64_t> &shape, | |||
| const void *data, size_t data_len) noexcept; | |||
| static MSTensor CreateRefTensor(const std::string &name, DataType type, const std::vector<int64_t> &shape, | |||
| const void *data, size_t data_len) noexcept; | |||
| api::DataType DataType() const; | |||
| void SetDataType(api::DataType type); | |||
| MSTensor(); | |||
| explicit MSTensor(const std::shared_ptr<Impl> &impl); | |||
| MSTensor(const std::string &name, DataType type, const std::vector<int64_t> &shape, const void *data, | |||
| size_t data_len); | |||
| ~MSTensor(); | |||
| const std::string &Name() const; | |||
| enum DataType DataType() const; | |||
| const std::vector<int64_t> &Shape() const; | |||
| void SetShape(const std::vector<int64_t> &shape); | |||
| int64_t ElementNum() const; | |||
| const void *Data() const; | |||
| std::shared_ptr<const void> Data() const; | |||
| void *MutableData(); | |||
| size_t DataSize() const; | |||
| bool ResizeData(size_t data_len); | |||
| bool SetData(const void *data, size_t data_len); | |||
| bool IsDevice() const; | |||
| int64_t ElementNum() const; | |||
| static int GetTypeSize(api::DataType type); | |||
| Tensor Clone() const; | |||
| MSTensor Clone() const; | |||
| bool operator==(std::nullptr_t) const; | |||
| private: | |||
| class Impl; | |||
| friend class ModelImpl; | |||
| explicit MSTensor(std::nullptr_t); | |||
| std::shared_ptr<Impl> impl_; | |||
| }; | |||
| class MSTensor::Impl { | |||
| public: | |||
| Impl() = default; | |||
| virtual ~Impl() = default; | |||
| virtual const std::string &Name() const = 0; | |||
| virtual enum DataType DataType() const = 0; | |||
| virtual const std::vector<int64_t> &Shape() const = 0; | |||
| virtual std::shared_ptr<const void> Data() const = 0; | |||
| virtual void *MutableData() = 0; | |||
| virtual size_t DataSize() const = 0; | |||
| virtual bool IsDevice() const = 0; | |||
| virtual std::shared_ptr<Impl> Clone() const = 0; | |||
| }; | |||
| class MS_API Buffer { | |||
| public: | |||
| Buffer(); | |||
| @@ -108,20 +123,5 @@ class MS_API Buffer { | |||
| class Impl; | |||
| std::shared_ptr<Impl> impl_; | |||
| }; | |||
| extern MS_API const char *kDeviceTypeAscend310; | |||
| extern MS_API const char *kDeviceTypeAscend910; | |||
| constexpr auto kModelOptionDumpCfgPath = "mindspore.option.dump_config_file_path"; | |||
| constexpr auto kModelOptionInsertOpCfgPath = "mindspore.option.insert_op_config_file_path"; // aipp config file | |||
| constexpr auto kModelOptionInputFormat = "mindspore.option.input_format"; // nchw or nhwc | |||
| // Mandatory while dynamic batch: e.g. "input_op_name1: n1,c2,h3,w4;input_op_name2: n4,c3,h2,w1" | |||
| constexpr auto kModelOptionInputShape = "mindspore.option.input_shape"; | |||
| constexpr auto kModelOptionOutputType = "mindspore.option.output_type"; // "FP32", "UINT8" or "FP16", default as "FP32" | |||
| constexpr auto kModelOptionPrecisionMode = "mindspore.option.precision_mode"; | |||
| // "force_fp16", "allow_fp32_to_fp16", "must_keep_origin_dtype" or "allow_mix_precision", default as "force_fp16" | |||
| constexpr auto kModelOptionOpSelectImplMode = "mindspore.option.op_select_impl_mode"; | |||
| // "high_precision" or "high_performance", default as "high_performance" | |||
| } // namespace api | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_INCLUDE_API_TYPES_H | |||
| @@ -0,0 +1,25 @@ | |||
| /** | |||
| * 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_STUB_SERVING_LOG_ADAPTER_H | |||
| #define MINDSPORE_STUB_SERVING_LOG_ADAPTER_H | |||
| #include "common/serving_common.h" | |||
| #define MS_LOG MSI_LOG | |||
| #define MS_EXCEPTION_IF_NULL MSI_EXCEPTION_IF_NULL | |||
| #endif // MINDSPORE_STUB_SERVING_LOG_ADAPTER_H | |||
| @@ -0,0 +1,47 @@ | |||
| /** | |||
| * 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_STUB_SERVING_UTILS_H | |||
| #define MINDSPORE_STUB_SERVING_UTILS_H | |||
| #include <memory> | |||
| #include <atomic> | |||
| #include <string> | |||
| #include <vector> | |||
| #include "utils/log_adapter.h" | |||
| namespace mindspore { | |||
| class FuncGraph {}; | |||
| using FuncGraphPtr = std::shared_ptr<FuncGraph>; | |||
| namespace common { | |||
| static inline const char *SafeCStr(const std::string &str) { | |||
| const int CACHED_STR_NUM = 1 << 8; | |||
| const int CACHED_STR_MASK = CACHED_STR_NUM - 1; | |||
| std::vector<std::string> STR_HOLDER(CACHED_STR_NUM); | |||
| static std::atomic<uint32_t> index{0}; | |||
| uint32_t cur_index = index++; | |||
| cur_index = cur_index & CACHED_STR_MASK; | |||
| STR_HOLDER[cur_index] = str; | |||
| return STR_HOLDER[cur_index].c_str(); | |||
| } | |||
| } // namespace common | |||
| } // namespace mindspore | |||
| #endif // MINDSPORE_STUB_SERVING_UTILS_H | |||
| @@ -1 +1 @@ | |||
| Subproject commit 06627661f43fb07761f3956e1a8b2c007c4e7987 | |||
| Subproject commit a24ff36d9c89ffbb8d56958718ffdec91837b409 | |||