forked from mindspore-Ecosystem/mindspore
sync kernel executor code.
This commit is contained in:
parent
f696a828cf
commit
20d6596026
|
@ -609,20 +609,6 @@ if(PLATFORM_ARM64)
|
|||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(MSLITE_ENABLE_KERNEL_EXECUTOR)
|
||||
install(DIRECTORY ${TOP_DIR}/mindspore/core/ops/ DESTINATION ${RUNTIME_INC_DIR}/core/ops
|
||||
COMPONENT ${RUNTIME_COMPONENT_NAME} FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY ${TOP_DIR}/mindspore/core/mindapi/ DESTINATION ${RUNTIME_INC_DIR}/core/mindapi
|
||||
COMPONENT ${RUNTIME_COMPONENT_NAME} FILES_MATCHING PATTERN "*.h")
|
||||
install(FILES ${TOP_DIR}/mindspore/lite/src/litert/cxx_api/kernel_executor/kernel_executor.h DESTINATION
|
||||
${RUNTIME_INC_DIR} COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
install(TARGETS kernel_executor DESTINATION ${RUNTIME_LIB_DIR} COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
install(TARGETS mindspore_core DESTINATION ${RUNTIME_LIB_DIR} COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
if(MSLITE_ENABLE_CONVERTER)
|
||||
install(FILES ${glog_LIBPATH}/libmindspore_glog.so.0.4.0 DESTINATION ${GLOG_DIR}
|
||||
RENAME libmindspore_glog.so.0 COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
endif()
|
||||
endif()
|
||||
elseif(PLATFORM_ARM32)
|
||||
if(SUPPORT_NPU)
|
||||
install(FILES ${DDK_LIB_PATH}/libhiai.so DESTINATION ${RUNTIME_DIR}/third_party/hiai_ddk/lib
|
||||
|
@ -1014,19 +1000,66 @@ else()
|
|||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(MSLITE_ENABLE_KERNEL_EXECUTOR)
|
||||
install(DIRECTORY ${TOP_DIR}/mindspore/core/ops/ DESTINATION ${RUNTIME_INC_DIR}/core/ops
|
||||
COMPONENT ${RUNTIME_COMPONENT_NAME} FILES_MATCHING PATTERN "*.h")
|
||||
install(DIRECTORY ${TOP_DIR}/mindspore/core/mindapi/ DESTINATION ${RUNTIME_INC_DIR}/core/mindapi
|
||||
COMPONENT ${RUNTIME_COMPONENT_NAME} FILES_MATCHING PATTERN "*.h")
|
||||
install(FILES ${TOP_DIR}/mindspore/lite/src/litert/cxx_api/kernel_executor/kernel_executor.h DESTINATION
|
||||
${RUNTIME_INC_DIR} COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
install(TARGETS kernel_executor DESTINATION ${RUNTIME_LIB_DIR} COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
install(TARGETS mindspore_core DESTINATION ${RUNTIME_LIB_DIR} COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
if(MSLITE_ENABLE_CONVERTER)
|
||||
install(FILES ${glog_LIBPATH}/libmindspore_glog.so.0.4.0
|
||||
DESTINATION ${GLOG_DIR} RENAME libmindspore_glog.so.0 COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MSLITE_ENABLE_KERNEL_EXECUTOR)
|
||||
install(FILES
|
||||
${TOP_DIR}/mindspore/core/ops/abs.h
|
||||
${TOP_DIR}/mindspore/core/ops/batch_norm.h
|
||||
${TOP_DIR}/mindspore/core/ops/ceil.h
|
||||
${TOP_DIR}/mindspore/core/ops/concat.h
|
||||
${TOP_DIR}/mindspore/core/ops/equal.h
|
||||
${TOP_DIR}/mindspore/core/ops/flatten.h
|
||||
${TOP_DIR}/mindspore/core/ops/gather.h
|
||||
${TOP_DIR}/mindspore/core/ops/gather_nd.h
|
||||
${TOP_DIR}/mindspore/core/ops/maximum.h
|
||||
${TOP_DIR}/mindspore/core/ops/minimum.h
|
||||
${TOP_DIR}/mindspore/core/ops/reshape.h
|
||||
${TOP_DIR}/mindspore/core/ops/softmax.h
|
||||
${TOP_DIR}/mindspore/core/ops/strided_slice.h
|
||||
${TOP_DIR}/mindspore/core/ops/transpose.h
|
||||
${TOP_DIR}/mindspore/core/ops/base_operator.h
|
||||
${TOP_DIR}/mindspore/core/ops/custom.h
|
||||
${TOP_DIR}/mindspore/core/ops/add.h
|
||||
${TOP_DIR}/mindspore/core/ops/arg_max.h
|
||||
${TOP_DIR}/mindspore/core/ops/arg_min.h
|
||||
${TOP_DIR}/mindspore/core/ops/avg_pool.h
|
||||
${TOP_DIR}/mindspore/core/ops/conv2d.h
|
||||
${TOP_DIR}/mindspore/core/ops/conv2d_transpose.h
|
||||
${TOP_DIR}/mindspore/core/ops/div.h
|
||||
${TOP_DIR}/mindspore/core/ops/mat_mul.h
|
||||
${TOP_DIR}/mindspore/core/ops/max_pool.h
|
||||
${TOP_DIR}/mindspore/core/ops/mul.h
|
||||
${TOP_DIR}/mindspore/core/ops/pad.h
|
||||
${TOP_DIR}/mindspore/core/ops/prelu.h
|
||||
${TOP_DIR}/mindspore/core/ops/topk.h
|
||||
${TOP_DIR}/mindspore/core/ops/relu.h
|
||||
${TOP_DIR}/mindspore/core/ops/sigmoid.h
|
||||
DESTINATION ${RUNTIME_INC_DIR}/ops
|
||||
COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
install(FILES
|
||||
${TOP_DIR}/mindspore/core/mindapi/base/format.h
|
||||
${TOP_DIR}/mindspore/core/mindapi/base/type_id.h
|
||||
${TOP_DIR}/mindspore/core/mindapi/base/types.h
|
||||
${TOP_DIR}/mindspore/core/mindapi/base/macros.h
|
||||
${TOP_DIR}/mindspore/core/mindapi/base/shared_ptr.h
|
||||
${TOP_DIR}/mindspore/core/mindapi/base/type_traits.h
|
||||
${TOP_DIR}/mindspore/core/mindapi/base/base.h
|
||||
DESTINATION ${RUNTIME_INC_DIR}/mindapi/base
|
||||
COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
install(FILES
|
||||
${TOP_DIR}/mindspore/core/mindapi/ir/common.h
|
||||
${TOP_DIR}/mindspore/core/mindapi/ir/primitive.h
|
||||
${TOP_DIR}/mindspore/core/mindapi/ir/value.h
|
||||
DESTINATION ${RUNTIME_INC_DIR}/mindapi/ir
|
||||
COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
install(FILES ${TOP_DIR}/mindspore/lite/src/litert/cxx_api/kernel_executor/kernel_executor.h DESTINATION
|
||||
${RUNTIME_INC_DIR}/api COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
install(TARGETS kernel_executor DESTINATION ${RUNTIME_LIB_DIR} COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
install(TARGETS mindspore_core DESTINATION ${RUNTIME_LIB_DIR} COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
if(MSLITE_ENABLE_CONVERTER)
|
||||
install(FILES ${glog_LIBPATH}/libmindspore_glog.so.0.4.0 DESTINATION ${RUNTIME_LIB_DIR}
|
||||
RENAME libmindspore_glog.so.0 COMPONENT ${RUNTIME_COMPONENT_NAME})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ endif()
|
|||
add_library(kernel_executor SHARED
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_executor.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kernel_executor_impl.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/op_converter.cc
|
||||
${TOP_DIR}/mindspore/lite/src/common/ops/ops_utils.cc
|
||||
${TOP_DIR}/mindspore/lite/src/common/primitive_t_utils.cc
|
||||
${TOP_DIR}/mindspore/lite/src/common/ops/ops_def.cc)
|
||||
|
@ -25,7 +26,6 @@ target_link_libraries(kernel_executor
|
|||
mindspore-lite
|
||||
mindspore_core
|
||||
mindspore::json
|
||||
mindspore::protobuf
|
||||
mindspore::flatbuffers)
|
||||
|
||||
if(USE_GLOG)
|
||||
|
|
|
@ -59,7 +59,7 @@ class MS_API KernelExecutor {
|
|||
const std::shared_ptr<Context> &ms_context, const int output_num);
|
||||
|
||||
/// \brief ReSize KernelExecutor. Change the shape and data type of inputs.
|
||||
/// Notice: Conv2DFusion can't update weight and bias by this method.
|
||||
/// Notice: Conv2D can't update weight and bias by this method.
|
||||
///
|
||||
/// \param[in] inputs A vector where single operator inputs are arranged in sequence.
|
||||
///
|
||||
|
@ -69,7 +69,9 @@ class MS_API KernelExecutor {
|
|||
/// \brief Execute KernelExecutor.
|
||||
///
|
||||
/// \param[in] inputs A vector where single operator inputs are arranged in sequence.
|
||||
/// Notices: inputs Tensor should be freed by user.
|
||||
/// \param[in] outputs Which is a pointer to a vector.The outputs are filled in the container in sequence.
|
||||
/// Notices: outputs Tensor will be freed by ~KernelExecutorImpl(), user needn't free it.
|
||||
///
|
||||
/// \return Status.
|
||||
Status Execute(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs);
|
||||
|
|
|
@ -27,25 +27,31 @@
|
|||
#include "src/litert/infer_manager.h"
|
||||
#include "src/litert/kernel_registry.h"
|
||||
#include "src/litert/cxx_api/kernel_executor/kernel_executor_impl.h"
|
||||
#include "src/litert/cxx_api/kernel_executor/op_converter.h"
|
||||
#include "src/litert/cpu_info.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace {
|
||||
constexpr size_t INITIAL_SIZE = 1024;
|
||||
std::unordered_set<std::string> support_ops = {
|
||||
"Abs", "Activation", "AddFusion", "ArgMaxFusion", "ArgMinFusion", "AvgPoolFusion",
|
||||
"BatchNorm", "Ceil", "Concat", "Custom", "Conv2DFusion", "Conv2dTransposeFusion",
|
||||
"DivFusion", "Equal", "Flatten", "Gather", "GatherNd", "MatMulFusion",
|
||||
"Maximum", "MaxPoolFusion", "Minimum", "MulFusion", "PadFusion", "PReLUFusion",
|
||||
"Range", "Reshape", "Resize", "Softmax", "StridedSlice", "TopKFusion",
|
||||
"Transpose", "Where",
|
||||
"Abs", "ReLU", "Sigmoid", "Add", "Argmax", "Argmin", "AvgPool",
|
||||
"BatchNorm", "Ceil", "Concat", "Custom", "Conv2D", "Conv2DTranspose", "Div",
|
||||
"Equal", "Flatten", "Gather", "GatherNd", "MatMul", "Maximum", "MaxPool",
|
||||
"Minimum", "Mul", "Pad", "PReLU", "Reshape", "Softmax", "StridedSlice",
|
||||
"TopK", "Transpose",
|
||||
};
|
||||
std::unordered_map<std::string, int> ops_output_num = {
|
||||
{"ArgMaxFusion", 2},
|
||||
{"ArgMinFusion", 2},
|
||||
{"TopKFusion", 2},
|
||||
{"TopK", 2},
|
||||
};
|
||||
} // namespace
|
||||
|
||||
KernelExecutorImpl::KernelExecutorImpl() {
|
||||
fbb_ = std::make_shared<flatbuffers::FlatBufferBuilder>();
|
||||
#if defined(ENABLE_ARM) && defined(ENABLE_FP16)
|
||||
lite::CpuInfo cpu_info;
|
||||
support_fp16_ = cpu_info.ArmIsSupportFp16();
|
||||
#endif
|
||||
}
|
||||
|
||||
KernelExecutorImpl::~KernelExecutorImpl() {
|
||||
FreeAllResource();
|
||||
inputs_.clear();
|
||||
|
@ -67,7 +73,10 @@ Status KernelExecutorImpl::Build(const std::shared_ptr<ops::BaseOperator> &op, c
|
|||
return kLiteError;
|
||||
} else {
|
||||
int output_num = ops_output_num.find(op_name) != ops_output_num.end() ? ops_output_num.at(op_name) : 1;
|
||||
InitTensors(inputs, output_num);
|
||||
status = InitTensors(inputs, output_num);
|
||||
if (status != kSuccess) {
|
||||
return status;
|
||||
}
|
||||
status = GetCpuKernel(ms_context);
|
||||
}
|
||||
|
||||
|
@ -95,7 +104,10 @@ Status KernelExecutorImpl::Build(const std::shared_ptr<ops::Custom> &op, const s
|
|||
if (status != kSuccess) {
|
||||
return status;
|
||||
}
|
||||
InitTensors(inputs, output_num);
|
||||
status = InitTensors(inputs, output_num);
|
||||
if (status != kSuccess) {
|
||||
return status;
|
||||
}
|
||||
status = GetCustomKernel(ms_context);
|
||||
if (status != kSuccess) {
|
||||
MS_LOG(ERROR) << "get custom kernel error.";
|
||||
|
@ -120,7 +132,10 @@ Status KernelExecutorImpl::ReSize(const std::vector<MSTensor> &inputs) {
|
|||
MS_LOG(ERROR) << "wrong inputs size.";
|
||||
return kLiteError;
|
||||
}
|
||||
InitTensors(inputs, 0);
|
||||
auto status = InitTensors(inputs, 0);
|
||||
if (status != kSuccess) {
|
||||
return status;
|
||||
}
|
||||
kernel_->set_in_tensors(inputs_);
|
||||
kernel_->set_out_tensors(outputs_);
|
||||
int ret;
|
||||
|
@ -131,6 +146,7 @@ Status KernelExecutorImpl::ReSize(const std::vector<MSTensor> &inputs) {
|
|||
}
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "do infer shape error.";
|
||||
FreeAllResource();
|
||||
return static_cast<StatusCode>(ret);
|
||||
}
|
||||
ret = kernel_->ReSize();
|
||||
|
@ -169,6 +185,7 @@ Status KernelExecutorImpl::Execute(const std::vector<MSTensor> &inputs, std::vec
|
|||
}
|
||||
auto lite_impl = std::static_pointer_cast<LiteTensorImpl>(user_input.impl());
|
||||
inputs_[i] = static_cast<lite::Tensor *>(lite_impl->lite_tensor());
|
||||
inputs_[i]->set_category(lite::Category::GRAPH_INPUT);
|
||||
}
|
||||
kernel_->set_in_tensors(inputs_);
|
||||
int ret = kernel_->Execute();
|
||||
|
@ -197,15 +214,24 @@ Status KernelExecutorImpl::BuildInit(const std::shared_ptr<ops::BaseOperator> &o
|
|||
return kLiteNullptr;
|
||||
}
|
||||
FreeAllResource();
|
||||
data_type_ = static_cast<enum TypeId>(inputs[FIRST_INPUT].DataType());
|
||||
if (data_type_ != kNumberTypeInt8 && data_type_ != kNumberTypeFloat16 && data_type_ != kNumberTypeFloat32) {
|
||||
MS_LOG(ERROR) << "unsupported datatype.";
|
||||
return kLiteNullptr;
|
||||
auto converter_op = op;
|
||||
auto op_creator = lite::OpsConverterRegistry::GetInstance()->GetOpsConverterCreator(op->name());
|
||||
if (op_creator != nullptr) {
|
||||
converter_op = op_creator(op);
|
||||
}
|
||||
std::unique_ptr<mindspore::schema::PrimitiveT> prim_t = lite::GetPrimitiveT(op);
|
||||
flatbuffers::FlatBufferBuilder fbb(INITIAL_SIZE);
|
||||
primitive_ = lite::ConvertToPrimitive(prim_t.get(), &fbb);
|
||||
fbb.Clear();
|
||||
data_type_ = static_cast<enum TypeId>(inputs[FIRST_INPUT].DataType());
|
||||
if (op->name() != "Custom") {
|
||||
if (data_type_ != kNumberTypeFloat32 && data_type_ != kNumberTypeFloat16) {
|
||||
MS_LOG(ERROR) << "unsupported datatype.";
|
||||
return kLiteError;
|
||||
} else if (data_type_ == kNumberTypeFloat16 && !support_fp16_) {
|
||||
MS_LOG(ERROR) << "inputs dataType is Fp16 but Hw cap NOT support FP16.";
|
||||
return kLiteError;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<mindspore::schema::PrimitiveT> prim_t = lite::GetPrimitiveT(converter_op);
|
||||
primitive_ = lite::ConvertToPrimitive(prim_t.get(), fbb_.get());
|
||||
if (primitive_ == nullptr) {
|
||||
MS_LOG(ERROR) << "convert to primitive nullptr.";
|
||||
return kLiteNullptr;
|
||||
|
@ -255,14 +281,17 @@ Status KernelExecutorImpl::GetCustomKernel(const std::shared_ptr<Context> &ms_co
|
|||
get_kernel = lite::KernelRegistry::GetInstance()->GetKernelExec(inputs_, outputs_, context_.get(), ms_context.get(),
|
||||
desc, nullptr, &kernel_, primitive_);
|
||||
}
|
||||
|
||||
// if found kernel, do infershape
|
||||
if (get_kernel == RET_OK) {
|
||||
int ret = KernelInferShape(inputs_, outputs_, primitive_, context_->GetProviders(), schema_version_);
|
||||
return static_cast<StatusCode>(ret);
|
||||
if (get_kernel != RET_OK) {
|
||||
MS_LOG(ERROR) << "get custom KernelExec error.";
|
||||
return static_cast<StatusCode>(get_kernel);
|
||||
}
|
||||
|
||||
return static_cast<StatusCode>(get_kernel);
|
||||
int ret = KernelInferShape(inputs_, outputs_, primitive_, context_->GetProviders(), schema_version_);
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "custom kernel infer shape error. please check inputs size and shape.";
|
||||
return static_cast<StatusCode>(ret);
|
||||
}
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
Status KernelExecutorImpl::GetCpuKernel(const std::shared_ptr<Context> &ms_context) {
|
||||
|
@ -274,38 +303,40 @@ Status KernelExecutorImpl::GetCpuKernel(const std::shared_ptr<Context> &ms_conte
|
|||
kernel::KernelKey desc{kernel::KERNEL_ARCH::kCPU, data_type_, NHWC, prim_type_};
|
||||
int get_kernel = lite::KernelRegistry::GetInstance()->GetKernelExec(inputs_, outputs_, context_.get(),
|
||||
ms_context.get(), desc, parameter_, &kernel_);
|
||||
if (get_kernel == RET_OK) {
|
||||
int ret = KernelInferShape(inputs_, outputs_, parameter_);
|
||||
return static_cast<StatusCode>(ret);
|
||||
if (get_kernel != RET_OK) {
|
||||
MS_LOG(ERROR) << "get cpu KernelExec error.";
|
||||
return static_cast<StatusCode>(get_kernel);
|
||||
}
|
||||
|
||||
return static_cast<StatusCode>(get_kernel);
|
||||
int ret = KernelInferShape(inputs_, outputs_, parameter_);
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "cpu kernel infer shape error. please check inputs size and shape.";
|
||||
return static_cast<StatusCode>(ret);
|
||||
}
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
void KernelExecutorImpl::InitTensors(const std::vector<MSTensor> &inputs, const int output_num) {
|
||||
Status KernelExecutorImpl::InitTensors(const std::vector<MSTensor> &inputs, const int output_num) {
|
||||
inputs_.clear();
|
||||
for (const auto &tensor : inputs) {
|
||||
if (tensor.impl() == nullptr) {
|
||||
MS_LOG(ERROR) << "Tensor " << tensor.Name() << " is nullptr.";
|
||||
return kLiteNullptr;
|
||||
}
|
||||
auto lite_impl = std::static_pointer_cast<LiteTensorImpl>(tensor.impl());
|
||||
auto lite_tensor = static_cast<lite::Tensor *>(lite_impl->lite_tensor());
|
||||
if (data_type_ == kNumberTypeInt8 && lite_tensor->quant_params().empty()) {
|
||||
Int8TensorAddQuantParam(lite_tensor);
|
||||
}
|
||||
inputs_.emplace_back(lite_tensor);
|
||||
}
|
||||
for (int i = 0; i < output_num; ++i) {
|
||||
lite::Tensor *output_tensor = new (std::nothrow) lite::Tensor();
|
||||
if (output_tensor == nullptr) {
|
||||
MS_LOG(ERROR) << "Failed to allocate tensor.";
|
||||
return kLiteNullptr;
|
||||
}
|
||||
output_tensor->set_category(lite::Category::VAR);
|
||||
if (data_type_ == kNumberTypeInt8) {
|
||||
Int8TensorAddQuantParam(output_tensor);
|
||||
}
|
||||
outputs_.emplace_back(output_tensor);
|
||||
}
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
void KernelExecutorImpl::FreeAllResource() {
|
||||
|
@ -374,11 +405,4 @@ bool KernelExecutorImpl::TensorIsValid(const MSTensor &ms_tensor, const lite::Te
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void KernelExecutorImpl::Int8TensorAddQuantParam(lite::Tensor *lite_tensor) {
|
||||
lite::LiteQuantParam quant_param;
|
||||
quant_param.scale = 1;
|
||||
quant_param.zeroPoint = 0;
|
||||
lite_tensor->set_quant_params({quant_param});
|
||||
}
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
namespace mindspore {
|
||||
class KernelExecutorImpl {
|
||||
public:
|
||||
KernelExecutorImpl() = default;
|
||||
KernelExecutorImpl();
|
||||
~KernelExecutorImpl();
|
||||
Status Build(const std::shared_ptr<ops::BaseOperator> &op, const std::vector<MSTensor> &inputs,
|
||||
const std::shared_ptr<Context> &ms_context);
|
||||
|
@ -41,11 +41,10 @@ class KernelExecutorImpl {
|
|||
Status GetCustomKernel(const std::shared_ptr<Context> &ms_context);
|
||||
Status GetCpuKernel(const std::shared_ptr<Context> &ms_context);
|
||||
Status GetOpParameter();
|
||||
void InitTensors(const std::vector<MSTensor> &inputs, const int output_num);
|
||||
Status InitTensors(const std::vector<MSTensor> &inputs, const int output_num);
|
||||
void FreeAllResource();
|
||||
std::vector<MSTensor> GetOutputs();
|
||||
bool TensorIsValid(const MSTensor &ms_tensor, const lite::Tensor *lite_tensor);
|
||||
void Int8TensorAddQuantParam(lite::Tensor *lite_tensor);
|
||||
|
||||
private:
|
||||
const schema::Primitive *primitive_ = nullptr;
|
||||
|
@ -57,6 +56,8 @@ class KernelExecutorImpl {
|
|||
std::vector<lite::Tensor *> inputs_;
|
||||
std::vector<lite::Tensor *> outputs_;
|
||||
int schema_version_ = lite::SCHEMA_VERSION::SCHEMA_CUR;
|
||||
std::shared_ptr<flatbuffers::FlatBufferBuilder> fbb_;
|
||||
bool support_fp16_ = false;
|
||||
};
|
||||
} // namespace mindspore
|
||||
#endif // MINDSPORE_LITE_SRC_RUNTIME_CXX_API_KERNEL_EXECUTOR_KERNEL_EXECUTOR_IMPL_H_
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* Copyright 2022 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 "src/litert/cxx_api/kernel_executor/op_converter.h"
|
||||
#include "ops/relu.h"
|
||||
#include "ops/fusion/activation.h"
|
||||
#include "ops/fusion/add_fusion.h"
|
||||
#include "ops/fusion/arg_max_fusion.h"
|
||||
#include "ops/fusion/arg_min_fusion.h"
|
||||
#include "ops/fusion/avg_pool_fusion.h"
|
||||
#include "ops/fused_batch_norm.h"
|
||||
#include "ops/batch_norm.h"
|
||||
#include "ops/fusion/conv2d_fusion.h"
|
||||
#include "ops/fusion/conv2d_transpose_fusion.h"
|
||||
#include "ops/fusion/div_fusion.h"
|
||||
#include "ops/fusion/mat_mul_fusion.h"
|
||||
#include "ops/fusion/max_pool_fusion.h"
|
||||
#include "ops/fusion/mul_fusion.h"
|
||||
#include "ops/fusion/pad_fusion.h"
|
||||
#include "ops/fusion/prelu_fusion.h"
|
||||
#include "ops/fusion/topk_fusion.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
std::shared_ptr<ops::BaseOperator> ReLUConverterCreators(const std::shared_ptr<ops::BaseOperator> &op) {
|
||||
auto op_converter = std::make_shared<ops::Activation>();
|
||||
op_converter->set_activation_type(ActivationType::RELU);
|
||||
return op_converter;
|
||||
}
|
||||
|
||||
std::shared_ptr<ops::BaseOperator> SigmoidConverterCreators(const std::shared_ptr<ops::BaseOperator> &op) {
|
||||
auto op_converter = std::make_shared<ops::Activation>();
|
||||
op_converter->set_activation_type(ActivationType::SIGMOID);
|
||||
return op_converter;
|
||||
}
|
||||
|
||||
template <class T, class T2>
|
||||
std::shared_ptr<ops::BaseOperator> CommonConverterCreators(const std::shared_ptr<ops::BaseOperator> &op) {
|
||||
auto op_cast = std::dynamic_pointer_cast<T>(op);
|
||||
auto op_converter = std::make_shared<T2>();
|
||||
op_converter->SetAttrs(op_cast->attrs());
|
||||
return op_converter;
|
||||
}
|
||||
|
||||
std::shared_ptr<ops::BaseOperator> ArgMinConverterCreators(const std::shared_ptr<ops::BaseOperator> &op) {
|
||||
auto op_converter = CommonConverterCreators<ops::ArgMin, ops::ArgMinFusion>(op);
|
||||
auto op_arg = std::dynamic_pointer_cast<ops::ArgMinFusion>(op_converter);
|
||||
op_arg->set_top_k(1);
|
||||
op_arg->set_keep_dims(true);
|
||||
return op_converter;
|
||||
}
|
||||
|
||||
std::shared_ptr<ops::BaseOperator> ArgMaxConverterCreators(const std::shared_ptr<ops::BaseOperator> &op) {
|
||||
auto op_converter = CommonConverterCreators<ops::Argmax, ops::ArgMaxFusion>(op);
|
||||
auto op_arg = std::dynamic_pointer_cast<ops::ArgMaxFusion>(op_converter);
|
||||
op_arg->set_top_k(1);
|
||||
op_arg->set_keep_dims(true);
|
||||
return op_converter;
|
||||
}
|
||||
|
||||
std::shared_ptr<ops::BaseOperator> TopKConverterCreators(const std::shared_ptr<ops::BaseOperator> &op) {
|
||||
auto op_converter = CommonConverterCreators<ops::TopK, ops::TopKFusion>(op);
|
||||
auto op_topk = std::dynamic_pointer_cast<ops::TopKFusion>(op_converter);
|
||||
op_topk->set_axis(-1);
|
||||
return op_converter;
|
||||
}
|
||||
|
||||
static RegistryOpsConverter g_ReLUConverterCreatorRegistry("ReLU", ReLUConverterCreators);
|
||||
static RegistryOpsConverter g_SigmoidConverterCreatorRegistry("Sigmoid", SigmoidConverterCreators);
|
||||
static RegistryOpsConverter g_AddConverterCreatorRegistry("Add", CommonConverterCreators<ops::Add, ops::AddFusion>);
|
||||
static RegistryOpsConverter g_ArgmaxConverterCreatorRegistry("Argmax", ArgMaxConverterCreators);
|
||||
static RegistryOpsConverter g_ArgminConverterCreatorRegistry("Argmin", ArgMinConverterCreators);
|
||||
|
||||
static RegistryOpsConverter g_AvgPoolConverterCreatorRegistry(
|
||||
"AvgPool", CommonConverterCreators<ops::AvgPool, ops::AvgPoolFusion>);
|
||||
static RegistryOpsConverter g_BatchNormConverterCreatorRegistry(
|
||||
"BatchNorm", CommonConverterCreators<ops::BatchNorm, ops::FusedBatchNorm>);
|
||||
static RegistryOpsConverter g_Conv2DConverterCreatorRegistry("Conv2D",
|
||||
CommonConverterCreators<ops::Conv2D, ops::Conv2DFusion>);
|
||||
static RegistryOpsConverter g_Conv2DTransposeConverterCreatorRegistry(
|
||||
"Conv2DTranspose", CommonConverterCreators<ops::Conv2DTranspose, ops::Conv2dTransposeFusion>);
|
||||
static RegistryOpsConverter g_DivConverterCreatorRegistry("Div", CommonConverterCreators<ops::Div, ops::DivFusion>);
|
||||
static RegistryOpsConverter g_MatMulConverterCreatorRegistry("MatMul",
|
||||
CommonConverterCreators<ops::MatMul, ops::MatMulFusion>);
|
||||
static RegistryOpsConverter g_MaxPoolConverterCreatorRegistry(
|
||||
"MaxPool", CommonConverterCreators<ops::MaxPool, ops::MaxPoolFusion>);
|
||||
static RegistryOpsConverter g_MulConverterCreatorRegistry("Mul", CommonConverterCreators<ops::Mul, ops::MulFusion>);
|
||||
static RegistryOpsConverter g_PadConverterCreatorRegistry("Pad", CommonConverterCreators<ops::Pad, ops::PadFusion>);
|
||||
static RegistryOpsConverter g_PReLUConverterCreatorRegistry("PReLU",
|
||||
CommonConverterCreators<ops::PReLU, ops::PReLUFusion>);
|
||||
static RegistryOpsConverter g_TopkConverterCreatorRegistry("TopK", TopKConverterCreators);
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Copyright 2022 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MINDSPORE_LITE_SRC_RUNTIME_CXX_API_KERNEL_EXECUTOR_OP_CONVERTER_H_
|
||||
#define MINDSPORE_LITE_SRC_RUNTIME_CXX_API_KERNEL_EXECUTOR_OP_CONVERTER_H_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include "ops/base_operator.h"
|
||||
#include "src/common/log_adapter.h"
|
||||
#include "include/api/types.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
typedef std::shared_ptr<mindspore::ops::BaseOperator> (*OpsConverterCreator)(
|
||||
const std::shared_ptr<mindspore::ops::BaseOperator> &op);
|
||||
|
||||
class OpsConverterRegistry {
|
||||
public:
|
||||
static OpsConverterRegistry *GetInstance() {
|
||||
static OpsConverterRegistry registry;
|
||||
return ®istry;
|
||||
}
|
||||
void InsertOpsMap(const std::string &name, OpsConverterCreator creator) { ops_converter_creators_[name] = creator; }
|
||||
OpsConverterCreator GetOpsConverterCreator(const std::string &name) {
|
||||
if (ops_converter_creators_.find(name) != ops_converter_creators_.end()) {
|
||||
return ops_converter_creators_[name];
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::map<std::string, OpsConverterCreator> ops_converter_creators_ = {};
|
||||
};
|
||||
|
||||
class RegistryOpsConverter {
|
||||
public:
|
||||
RegistryOpsConverter(const std::string &name, OpsConverterCreator creator) noexcept {
|
||||
OpsConverterRegistry::GetInstance()->InsertOpsMap(name, creator);
|
||||
}
|
||||
~RegistryOpsConverter() = default;
|
||||
};
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
||||
#endif
|
|
@ -173,3 +173,8 @@ if [ "$MSLITE_ENABLE_SERVER_INFERENCE" = on ];then
|
|||
echo 'run ModelParallelRunner api ut test'
|
||||
./lite-test --gtest_filter="ModelParallelRunnerTest.*"
|
||||
fi
|
||||
|
||||
if [ "$MSLITE_ENABLE_KERNEL_EXECUTOR" = on ];then
|
||||
echo 'run kernel executor api ut test'
|
||||
./lite-test --gtest_filter="KernelExecutorTest.*"
|
||||
fi
|
||||
|
|
|
@ -13,76 +13,761 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <vector>
|
||||
#include "common/common_test.h"
|
||||
#include "include/registry/register_kernel_interface.h"
|
||||
#include "include/registry/register_kernel.h"
|
||||
#include "src/litert/cxx_api/kernel_executor/kernel_executor.h"
|
||||
#include "ops/add.h"
|
||||
#include "ops/transpose.h"
|
||||
#include "ops/arg_max.h"
|
||||
#include "ops/batch_norm.h"
|
||||
#include "ops/conv2d.h"
|
||||
#include "ops/mat_mul.h"
|
||||
#include "ops/topk.h"
|
||||
#include "ops/arg_min.h"
|
||||
#include "ops/avg_pool.h"
|
||||
#include "ops/ceil.h"
|
||||
#include "ops/concat.h"
|
||||
#include "ops/conv2d_transpose.h"
|
||||
#include "ops/flatten.h"
|
||||
#include "ops/gather.h"
|
||||
#include "ops/gather_nd.h"
|
||||
#include "ops/maximum.h"
|
||||
#include "ops/max_pool.h"
|
||||
#include "ops/minimum.h"
|
||||
#include "ops/mul.h"
|
||||
#include "ops/pad.h"
|
||||
#include "ops/prelu.h"
|
||||
#include "ops/reshape.h"
|
||||
#include "ops/softmax.h"
|
||||
#include "ops/strided_slice.h"
|
||||
#include "ops/abs.h"
|
||||
#include "ops/div.h"
|
||||
#include "ops/equal.h"
|
||||
#include "ops/relu.h"
|
||||
#include "ops/base_operator.h"
|
||||
#include "ops/sigmoid.h"
|
||||
#include "ops/addn.h"
|
||||
|
||||
namespace mindspore {
|
||||
class KernelExecutorTest : public mindspore::CommonTest {
|
||||
public:
|
||||
KernelExecutorTest();
|
||||
~KernelExecutorTest();
|
||||
~KernelExecutorTest() = default;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<mindspore::ops::Abs> op_ = std::make_shared<mindspore::ops::Abs>();
|
||||
std::shared_ptr<mindspore::Context> context_ = std::make_shared<mindspore::Context>();
|
||||
float *input_data_;
|
||||
std::shared_ptr<mindspore::KernelExecutor> kernel_executor_;
|
||||
std::shared_ptr<mindspore::Context> context_;
|
||||
std::vector<float> input_data_;
|
||||
};
|
||||
|
||||
KernelExecutorTest::KernelExecutorTest() {
|
||||
kernel_executor_ = std::make_shared<mindspore::KernelExecutor>();
|
||||
context_ = std::make_shared<mindspore::Context>();
|
||||
auto cpu_context = std::make_shared<mindspore::CPUDeviceInfo>();
|
||||
context_->MutableDeviceInfo().push_back(cpu_context);
|
||||
context_->SetThreadNum(1);
|
||||
|
||||
input_data_ = new float[12]{-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12};
|
||||
input_data_ = {-1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12};
|
||||
}
|
||||
|
||||
KernelExecutorTest::~KernelExecutorTest() { delete[] input_data_; }
|
||||
namespace {
|
||||
const auto kFloat32 = DataType::kNumberTypeFloat32;
|
||||
class CustomAddKernel : public kernel::Kernel {
|
||||
public:
|
||||
CustomAddKernel(const std::vector<MSTensor> &inputs, const std::vector<MSTensor> &outputs,
|
||||
const schema::Primitive *primitive, const mindspore::Context *ctx)
|
||||
: Kernel(inputs, outputs, primitive, ctx) {}
|
||||
~CustomAddKernel() = default;
|
||||
|
||||
int Prepare() override { return static_cast<int>(kSuccess); }
|
||||
|
||||
int Execute() override {
|
||||
const float *in0 = static_cast<const float *>(inputs_[0].Data().get());
|
||||
const float *in1 = static_cast<const float *>(inputs_[1].Data().get());
|
||||
float *out = static_cast<float *>(outputs_[0].MutableData());
|
||||
auto num = outputs_[0].ElementNum();
|
||||
for (int i = 0; i < num; ++i) {
|
||||
out[i] = in0[i] + in1[i];
|
||||
}
|
||||
return static_cast<int>(kSuccess);
|
||||
}
|
||||
int ReSize() override { return static_cast<int>(kSuccess); }
|
||||
};
|
||||
|
||||
std::shared_ptr<kernel::Kernel> CustomAddCreator(const std::vector<MSTensor> &inputs,
|
||||
const std::vector<MSTensor> &outputs,
|
||||
const schema::Primitive *primitive, const mindspore::Context *ctx) {
|
||||
return std::make_shared<CustomAddKernel>(inputs, outputs, primitive, ctx);
|
||||
}
|
||||
REGISTER_CUSTOM_KERNEL(CPU, Tutorial, kFloat32, Custom_Add, CustomAddCreator)
|
||||
|
||||
class CustomAddInfer : public kernel::KernelInterface {
|
||||
public:
|
||||
CustomAddInfer() = default;
|
||||
~CustomAddInfer() = default;
|
||||
Status Infer(std::vector<mindspore::MSTensor> *inputs, std::vector<mindspore::MSTensor> *outputs,
|
||||
const schema::Primitive *primitive) override {
|
||||
(*outputs)[0].SetFormat((*inputs)[0].format());
|
||||
(*outputs)[0].SetDataType((*inputs)[0].DataType());
|
||||
(*outputs)[0].SetShape((*inputs)[0].Shape());
|
||||
return kSuccess;
|
||||
}
|
||||
};
|
||||
std::shared_ptr<kernel::KernelInterface> CustomAddInferCreator() { return std::make_shared<CustomAddInfer>(); }
|
||||
REGISTER_CUSTOM_KERNEL_INTERFACE(CustomOpTurial, Custom_Add, CustomAddInferCreator)
|
||||
} // namespace
|
||||
|
||||
TEST_F(KernelExecutorTest, TestBuild) {
|
||||
auto kernel_executor = std::make_shared<mindspore::KernelExecutor>();
|
||||
auto op = std::make_shared<ops::Abs>();
|
||||
std::vector<mindspore::MSTensor> inputs_abs;
|
||||
mindspore::MSTensor tensor_abs("Abs", mindspore::DataType::kNumberTypeFloat32, {1, 3, 2, 3},
|
||||
reinterpret_cast<void *>(input_data_), 12 * sizeof(float));
|
||||
reinterpret_cast<void *>(input_data_.data()), 12 * sizeof(float));
|
||||
inputs_abs.emplace_back(tensor_abs);
|
||||
ASSERT_EQ(kernel_executor->Build(nullptr, {}, nullptr), mindspore::kLiteNullptr);
|
||||
ASSERT_EQ(kernel_executor->Build(op_, {}, nullptr), mindspore::kLiteError);
|
||||
ASSERT_EQ(kernel_executor->Build(op_, inputs_abs, nullptr), mindspore::kLiteNullptr);
|
||||
ASSERT_EQ(kernel_executor->Build(op_, inputs_abs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Build(nullptr, {}, nullptr), mindspore::kLiteNullptr);
|
||||
ASSERT_EQ(kernel_executor_->Build(op, {}, nullptr), mindspore::kLiteError);
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs_abs, nullptr), mindspore::kLiteNullptr);
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs_abs, context_), mindspore::kSuccess);
|
||||
|
||||
auto addn = std::make_shared<ops::AddN>();
|
||||
ASSERT_EQ(kernel_executor_->Build(addn, inputs_abs, context_), mindspore::kLiteError);
|
||||
tensor_abs.SetDataType(mindspore::DataType::kNumberTypeInt8);
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs_abs, context_), mindspore::kLiteError);
|
||||
tensor_abs.SetDataType(mindspore::DataType::kNumberTypeFloat16);
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs_abs, context_), mindspore::kLiteError);
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestResize) {
|
||||
auto kernel_executor = std::make_shared<mindspore::KernelExecutor>();
|
||||
auto op = std::make_shared<ops::Abs>();
|
||||
std::vector<mindspore::MSTensor> inputs_abs;
|
||||
mindspore::MSTensor tensor_abs("Abs", mindspore::DataType::kNumberTypeFloat32, {1, 3, 2, 2},
|
||||
reinterpret_cast<void *>(input_data_), 12 * sizeof(float));
|
||||
reinterpret_cast<void *>(input_data_.data()), 12 * sizeof(float));
|
||||
inputs_abs.emplace_back(tensor_abs);
|
||||
|
||||
std::vector<mindspore::MSTensor> inputs_abs_resize;
|
||||
mindspore::MSTensor tensor_abs_resize("Abs", mindspore::DataType::kNumberTypeFloat32, {1, 4, 3},
|
||||
reinterpret_cast<void *>(input_data_), 12 * sizeof(float));
|
||||
inputs_abs.emplace_back(tensor_abs_resize);
|
||||
reinterpret_cast<void *>(input_data_.data()), 12 * sizeof(float));
|
||||
inputs_abs_resize.emplace_back(tensor_abs_resize);
|
||||
|
||||
ASSERT_EQ(kernel_executor->ReSize({}), mindspore::kLiteNullptr);
|
||||
kernel_executor->Build(op_, inputs_abs, context_);
|
||||
ASSERT_EQ(kernel_executor->ReSize({}), mindspore::kLiteError);
|
||||
ASSERT_EQ(kernel_executor->ReSize(inputs_abs_resize), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->ReSize({}), mindspore::kLiteNullptr);
|
||||
kernel_executor_->Build(nullptr, {}, nullptr);
|
||||
ASSERT_EQ(kernel_executor_->ReSize({}), mindspore::kLiteNullptr);
|
||||
kernel_executor_->Build(op, inputs_abs, context_);
|
||||
ASSERT_EQ(kernel_executor_->ReSize({}), mindspore::kLiteError);
|
||||
ASSERT_EQ(kernel_executor_->ReSize(inputs_abs_resize), mindspore::kSuccess);
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestExecute) {
|
||||
auto kernel_executor = std::make_shared<mindspore::KernelExecutor>();
|
||||
auto op = std::make_shared<ops::Abs>();
|
||||
std::vector<mindspore::MSTensor> inputs_abs;
|
||||
std::vector<mindspore::MSTensor> outputs_abs;
|
||||
mindspore::MSTensor tensor_abs("Abs", mindspore::DataType::kNumberTypeFloat32, {1, 3, 2, 2},
|
||||
reinterpret_cast<void *>(input_data_), 12 * sizeof(float));
|
||||
reinterpret_cast<void *>(input_data_.data()), 12 * sizeof(float));
|
||||
inputs_abs.emplace_back(tensor_abs);
|
||||
|
||||
ASSERT_EQ(kernel_executor->Execute(inputs_abs, &outputs_abs), mindspore::kLiteNullptr);
|
||||
kernel_executor->Build(nullptr, inputs_abs, nullptr);
|
||||
ASSERT_EQ(kernel_executor->Execute(inputs_abs, &outputs_abs), mindspore::kLiteNullptr);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs_abs, &outputs_abs), mindspore::kLiteNullptr);
|
||||
kernel_executor_->Build(nullptr, inputs_abs, nullptr);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs_abs, &outputs_abs), mindspore::kLiteNullptr);
|
||||
|
||||
kernel_executor->Build(op_, inputs_abs, context_);
|
||||
ASSERT_EQ(kernel_executor->Execute(inputs_abs, &outputs_abs), mindspore::kSuccess);
|
||||
kernel_executor_->Build(op, inputs_abs, context_);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs_abs, nullptr), mindspore::kLiteNullptr);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs_abs, &outputs_abs), mindspore::kSuccess);
|
||||
float correct[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs_abs[0].MutableData()), correct,
|
||||
outputs_abs[0].ElementNum(), 0.0001));
|
||||
|
||||
std::vector<mindspore::MSTensor> inputs_other;
|
||||
mindspore::MSTensor tensor_other("other", mindspore::DataType::kNumberTypeFloat32, {1, 3, 2, 2},
|
||||
reinterpret_cast<void *>(input_data_.data()), 12 * sizeof(float));
|
||||
inputs_other.emplace_back(tensor_other);
|
||||
tensor_other.SetShape({3, 1, 2, 2});
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs_other, &outputs_abs), mindspore::kLiteError);
|
||||
tensor_other.SetShape({1, 3, 4});
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs_other, &outputs_abs), mindspore::kLiteError);
|
||||
tensor_other.SetFormat(mindspore::NCHW);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs_other, &outputs_abs), mindspore::kLiteError);
|
||||
tensor_other.SetDataType(mindspore::DataType::kNumberTypeFloat16);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs_other, &outputs_abs), mindspore::kLiteError);
|
||||
inputs_other.emplace_back(tensor_abs);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs_other, &outputs_abs), mindspore::kLiteError);
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestCustom) {
|
||||
auto op = std::make_shared<ops::Custom>();
|
||||
auto kernel_executor = std::make_shared<mindspore::KernelExecutor>();
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor tensor("Custom", mindspore::DataType::kNumberTypeFloat32, {1, 3, 2, 2},
|
||||
reinterpret_cast<void *>(input_data_.data()), 12 * sizeof(float));
|
||||
inputs.emplace_back(tensor);
|
||||
inputs.emplace_back(tensor);
|
||||
|
||||
ASSERT_EQ(kernel_executor->Build(op, inputs, context_, 0), mindspore::kLiteError);
|
||||
ASSERT_EQ(kernel_executor->Build(op, inputs, context_), mindspore::kLiteError);
|
||||
ASSERT_EQ(kernel_executor->Build(op, inputs, context_, 1), mindspore::kLiteNotSupport);
|
||||
|
||||
std::map<std::string, std::vector<uint8_t>> custom_attrs;
|
||||
std::string input_num = std::to_string(2);
|
||||
std::vector<uint8_t> input_num_attr(input_num.begin(), input_num.end());
|
||||
custom_attrs["input_num"] = input_num_attr;
|
||||
std::string op_kind = "custom op";
|
||||
std::vector<uint8_t> op_kind_attr(op_kind.begin(), op_kind.end());
|
||||
custom_attrs["op_kind"] = op_kind_attr;
|
||||
op->Init("Custom_Add", custom_attrs);
|
||||
ASSERT_EQ(kernel_executor->Build(op, inputs, context_, 1), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {-2, 4, -6, 8, -10, 12, -14, 16, -18, 20, -22, 24};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestRelu) {
|
||||
auto op = std::make_shared<ops::ReLU>();
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor tensor("Relu", mindspore::DataType::kNumberTypeFloat32, {1, 3, 2, 2},
|
||||
reinterpret_cast<void *>(input_data_.data()), 12 * sizeof(float));
|
||||
inputs.emplace_back(tensor);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {0, 2, 0, 4, 0, 6, 0, 8, 0, 10, 0, 12};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestSigmoid) {
|
||||
auto op = std::make_shared<ops::Sigmoid>();
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
std::vector<float> input_data{1, 2, 3, 4, 5};
|
||||
mindspore::MSTensor tensor("Sigmoid", mindspore::DataType::kNumberTypeFloat32, {5},
|
||||
reinterpret_cast<void *>(input_data.data()), 5 * sizeof(float));
|
||||
inputs.emplace_back(tensor);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {0.731059, 0.88081, 0.952574, 0.982015, 0.993307};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestAdd) {
|
||||
auto op = std::make_shared<ops::Add>();
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor tensor("Add", mindspore::DataType::kNumberTypeFloat32, {1, 3, 2, 2},
|
||||
reinterpret_cast<void *>(input_data_.data()), 12 * sizeof(float));
|
||||
inputs.emplace_back(tensor);
|
||||
inputs.emplace_back(tensor);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {-2, 4, -6, 8, -10, 12, -14, 16, -18, 20, -22, 24};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestArgMax) {
|
||||
auto op = std::make_shared<ops::Argmax>();
|
||||
op->Init(-1);
|
||||
std::vector<float> argmax_data{1, 20, 5, 67, 8, 9, 130, 24, 15};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor tensor("Argmax", mindspore::DataType::kNumberTypeFloat32, {3, 3},
|
||||
reinterpret_cast<void *>(argmax_data.data()), 9 * sizeof(float));
|
||||
inputs.emplace_back(tensor);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
int32_t correct[] = {1, 0, 0};
|
||||
ASSERT_EQ(
|
||||
0, CompareOutputData(reinterpret_cast<int32_t *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(), 0));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestArgMin) {
|
||||
auto op = std::make_shared<ops::ArgMin>();
|
||||
op->Init();
|
||||
std::vector<float> input_data{2.0, 3.1, 1.2};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data.data()), 3 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
int32_t correct[] = {2};
|
||||
ASSERT_EQ(
|
||||
0, CompareOutputData(reinterpret_cast<int32_t *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(), 0));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestAvgPool) {
|
||||
auto op = std::make_shared<ops::AvgPool>();
|
||||
op->Init({2, 2}, {1, 1});
|
||||
std::vector<float> input_data{0, 12, 24, 1, 13, 25, 2, 14, 26, 3, 15, 27, 4, 16, 28, 5, 17, 29,
|
||||
6, 18, 30, 7, 19, 31, 8, 20, 32, 9, 21, 33, 10, 22, 34, 11, 23, 35};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {1, 3, 4, 3},
|
||||
reinterpret_cast<void *>(input_data.data()), 36 * sizeof(float));
|
||||
input.SetFormat(mindspore::Format::NHWC);
|
||||
inputs.emplace_back(input);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {2.5, 14.5, 26.5, 3.5, 15.5, 27.5, 4.5, 16.5, 28.5,
|
||||
6.5, 18.5, 30.5, 7.5, 19.5, 31.5, 8.5, 20.5, 32.5};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestBatchNorm) {
|
||||
auto op = std::make_shared<ops::BatchNorm>();
|
||||
op->Init(true);
|
||||
std::vector<float> input_data{1, 1, 1, 1};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {1, 1, 2, 2},
|
||||
reinterpret_cast<void *>(input_data.data()), 4 * sizeof(float));
|
||||
mindspore::MSTensor scale("input", mindspore::DataType::kNumberTypeFloat32, {2},
|
||||
reinterpret_cast<void *>(input_data.data()), 2 * sizeof(float));
|
||||
mindspore::MSTensor bias("input", mindspore::DataType::kNumberTypeFloat32, {2},
|
||||
reinterpret_cast<void *>(input_data.data()), 2 * sizeof(float));
|
||||
mindspore::MSTensor mean("input", mindspore::DataType::kNumberTypeFloat32, {2},
|
||||
reinterpret_cast<void *>(input_data.data()), 2 * sizeof(float));
|
||||
mindspore::MSTensor variance("input", mindspore::DataType::kNumberTypeFloat32, {2},
|
||||
reinterpret_cast<void *>(input_data.data()), 2 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(scale);
|
||||
inputs.emplace_back(bias);
|
||||
inputs.emplace_back(mean);
|
||||
inputs.emplace_back(variance);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {1, 1, 1, 1};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestCeil) {
|
||||
auto op = std::make_shared<ops::Ceil>();
|
||||
std::vector<float> input_data{1.1, 2.5, -1.5};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data.data()), 3 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {2, 3, -1};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestConcat) {
|
||||
auto op = std::make_shared<ops::Concat>();
|
||||
op->Init(1);
|
||||
std::vector<float> input_data{0, 1, 2, 1};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {2, 2},
|
||||
reinterpret_cast<void *>(input_data.data()), 4 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {0, 1, 0, 1, 2, 1, 2, 1};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestConv2D) {
|
||||
auto op = std::make_shared<ops::Conv2D>();
|
||||
op->Init(32, {3, 3});
|
||||
std::vector<float> input_data(10 * 32 * 32 * 32, 1);
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {10, 32, 32, 32},
|
||||
reinterpret_cast<void *>(input_data.data()), 10 * 32 * 32 * 32 * sizeof(float));
|
||||
mindspore::MSTensor weight("input", mindspore::DataType::kNumberTypeFloat32, {32, 3, 3, 32},
|
||||
reinterpret_cast<void *>(input_data.data()), 32 * 3 * 3 * 32 * sizeof(float));
|
||||
input.SetFormat(mindspore::Format::NHWC);
|
||||
weight.SetFormat(mindspore::Format::NHWC);
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(weight);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
std::vector<int64_t> shape{10, 30, 30, 32};
|
||||
ASSERT_EQ(outputs[0].Shape(), shape);
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestConv2DTranspose) {
|
||||
auto op = std::make_shared<ops::Conv2DTranspose>();
|
||||
op->Init(32, 32, {3, 3});
|
||||
std::vector<float> input_data(10 * 32 * 32 * 32, 1);
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {10, 30, 30, 32},
|
||||
reinterpret_cast<void *>(input_data.data()), 10 * 30 * 30 * 32 * sizeof(float));
|
||||
mindspore::MSTensor weight("input", mindspore::DataType::kNumberTypeFloat32, {32, 3, 3, 32},
|
||||
reinterpret_cast<void *>(input_data.data()), 32 * 3 * 3 * 32 * sizeof(float));
|
||||
input.SetFormat(mindspore::Format::NHWC);
|
||||
weight.SetFormat(mindspore::Format::NHWC);
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(weight);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
std::vector<int64_t> shape{10, 32, 32, 32};
|
||||
ASSERT_EQ(outputs[0].Shape(), shape);
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestDiv) {
|
||||
auto op = std::make_shared<ops::Div>();
|
||||
std::vector<float> input_data{-4, 5, 6};
|
||||
std::vector<float> input_data2{3, 2, 3};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data.data()), 3 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data2.data()), 3 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {-1.33333, 2.5, 2};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestEqual) {
|
||||
auto op = std::make_shared<ops::Equal>();
|
||||
std::vector<float> input_data{1, 2, 3};
|
||||
std::vector<float> input_data2{2};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data.data()), 3 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeFloat32, {1},
|
||||
reinterpret_cast<void *>(input_data2.data()), 1 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestFlatten) {
|
||||
auto op = std::make_shared<ops::Flatten>();
|
||||
std::vector<float> input_data(24, 1);
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {1, 2, 3, 4},
|
||||
reinterpret_cast<void *>(input_data.data()), 24 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
std::vector<int64_t> shape{1, 24};
|
||||
ASSERT_EQ(outputs[0].Shape(), shape);
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestGather) {
|
||||
auto op = std::make_shared<ops::Gather>();
|
||||
std::vector<float> input_data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
std::vector<float> input_data2{0, 2, 4, 2, 6};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {3, 4},
|
||||
reinterpret_cast<void *>(input_data.data()), 12 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeFloat32, {2},
|
||||
reinterpret_cast<void *>(input_data2.data()), 2 * sizeof(float));
|
||||
mindspore::MSTensor input3("input", mindspore::DataType::kNumberTypeFloat32, {1},
|
||||
reinterpret_cast<void *>(input_data2.data()), 1 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
inputs.emplace_back(input3);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {1, 2, 3, 4, 9, 10, 11, 12};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestGatherNd) {
|
||||
auto op = std::make_shared<ops::GatherNd>();
|
||||
std::vector<float> input_data{-0.1, 0.3, 3.6, 0.4, 0.5, -3.2};
|
||||
std::vector<int32_t> input_data2{0, 0, 1, 1};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {2, 3},
|
||||
reinterpret_cast<void *>(input_data.data()), 6 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeInt32, {2, 2},
|
||||
reinterpret_cast<void *>(input_data2.data()), 4 * sizeof(int32_t));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {-0.1, 0.5};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestMatMul) {
|
||||
auto op = std::make_shared<ops::MatMul>();
|
||||
std::vector<float> input_data(12, 1);
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {1, 3},
|
||||
reinterpret_cast<void *>(input_data.data()), 3 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeFloat32, {3, 4},
|
||||
reinterpret_cast<void *>(input_data.data()), 12 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {3, 3, 3, 3};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestMaximum) {
|
||||
auto op = std::make_shared<ops::Maximum>();
|
||||
std::vector<float> input_data{1, 5, 3};
|
||||
std::vector<float> input_data2{4, 2, 6};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data.data()), 3 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data2.data()), 3 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {4, 5, 6};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestMaxPool) {
|
||||
auto op = std::make_shared<ops::MaxPool>();
|
||||
op->Init({2, 2}, {1, 1});
|
||||
std::vector<float> input_data{0, 12, 24, 1, 13, 25, 2, 14, 26, 3, 15, 27, 4, 16, 28, 5, 17, 29,
|
||||
6, 18, 30, 7, 19, 31, 8, 20, 32, 9, 21, 33, 10, 22, 34, 11, 23, 35};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {1, 3, 4, 3},
|
||||
reinterpret_cast<void *>(input_data.data()), 36 * sizeof(float));
|
||||
input.SetFormat(mindspore::Format::NHWC);
|
||||
inputs.emplace_back(input);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {5, 17, 29, 6, 18, 30, 7, 19, 31, 9, 21, 33, 10, 22, 34, 11, 23, 35};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestMinimum) {
|
||||
auto op = std::make_shared<ops::Minimum>();
|
||||
std::vector<float> input_data{1, 5, 3};
|
||||
std::vector<float> input_data2{4, 2, 6};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data.data()), 3 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data2.data()), 3 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {1, 2, 3};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestMul) {
|
||||
auto op = std::make_shared<ops::Mul>();
|
||||
std::vector<float> input_data{1, 2, 3};
|
||||
std::vector<float> input_data2{4, 5, 6};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data.data()), 3 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data2.data()), 3 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {4, 10, 18};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestPad) {
|
||||
auto op = std::make_shared<ops::Pad>();
|
||||
std::vector<float> input_data{-0.1, 0.3, 3.6, 0.4, 0.5, -3.2};
|
||||
std::vector<int32_t> input_data2{1, 2, 2, 1};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {2, 3},
|
||||
reinterpret_cast<void *>(input_data.data()), 6 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeInt32, {4},
|
||||
reinterpret_cast<void *>(input_data2.data()), 4 * sizeof(int32_t));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {0, 0, 0, 0, 0, 0, 0, 0, -0.1, 0.3, 3.6, 0, 0, 0, 0.4,
|
||||
0.5, -3.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestPReLU) {
|
||||
auto op = std::make_shared<ops::PReLU>();
|
||||
std::vector<float> input_data{-6, -4, -2, -5, -3, -1, 0, 2, 4, 1, 3, 5};
|
||||
std::vector<float> input_data2{0.1, 0.6, -0.3};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {2, 1, 2, 3},
|
||||
reinterpret_cast<void *>(input_data.data()), 12 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeFloat32, {3},
|
||||
reinterpret_cast<void *>(input_data2.data()), 3 * sizeof(float));
|
||||
input.SetFormat(mindspore::Format::NHWC);
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {-0.6, -2.4, 0.6, -0.5, -1.8, 0.3, 0, 2, 4, 1, 3, 5};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestReshape) {
|
||||
auto op = std::make_shared<ops::Reshape>();
|
||||
std::vector<float> input_data{-0.1, 0.3, 3.6, 0.4, 0.5, -3.2};
|
||||
std::vector<int32_t> input_data2{3, 2};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {2, 3},
|
||||
reinterpret_cast<void *>(input_data.data()), 6 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeInt32, {2},
|
||||
reinterpret_cast<void *>(input_data2.data()), 2 * sizeof(int32_t));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {-0.1, 0.3, 3.6, 0.4, 0.5, -3.2};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
std::vector<int64_t> shape{3, 2};
|
||||
ASSERT_EQ(outputs[0].Shape(), shape);
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestSoftmax) {
|
||||
auto op = std::make_shared<ops::Softmax>();
|
||||
op->Init();
|
||||
std::vector<float> input_data{1, 2, 3, 4, 5};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {1, 5},
|
||||
reinterpret_cast<void *>(input_data.data()), 5 * sizeof(float));
|
||||
inputs.emplace_back(input);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {0.0116558, 0.0316853, 0.0861187, 0.234124, 0.636416};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestStridedSlice) {
|
||||
auto op = std::make_shared<ops::StridedSlice>();
|
||||
std::vector<float> input_data{1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
||||
std::vector<int32_t> input_data2{1, 0, 0};
|
||||
std::vector<int32_t> input_data3{2, 1, 3};
|
||||
std::vector<int32_t> input_data4{1, 1, 1};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {3, 2, 3},
|
||||
reinterpret_cast<void *>(input_data.data()), 18 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeInt32, {3},
|
||||
reinterpret_cast<void *>(input_data2.data()), 3 * sizeof(int32_t));
|
||||
mindspore::MSTensor input3("input", mindspore::DataType::kNumberTypeInt32, {3},
|
||||
reinterpret_cast<void *>(input_data3.data()), 3 * sizeof(int32_t));
|
||||
mindspore::MSTensor input4("input", mindspore::DataType::kNumberTypeInt32, {3},
|
||||
reinterpret_cast<void *>(input_data4.data()), 3 * sizeof(int32_t));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
inputs.emplace_back(input3);
|
||||
inputs.emplace_back(input4);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {3, 3, 3};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestTopK) {
|
||||
auto op = std::make_shared<ops::TopK>();
|
||||
op->Init(true);
|
||||
std::vector<float> input_data{1, 2, 3, 4, 5};
|
||||
std::vector<int32_t> input_data2{3};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {5},
|
||||
reinterpret_cast<void *>(input_data.data()), 5 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeInt32, {1},
|
||||
reinterpret_cast<void *>(input_data2.data()), 1 * sizeof(int32_t));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {5, 4, 3};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
|
||||
TEST_F(KernelExecutorTest, TestTranspose) {
|
||||
auto op = std::make_shared<ops::Transpose>();
|
||||
std::vector<float> input_data{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
std::vector<int32_t> input_data2{0, 2, 1};
|
||||
std::vector<mindspore::MSTensor> inputs;
|
||||
std::vector<mindspore::MSTensor> outputs;
|
||||
mindspore::MSTensor input("input", mindspore::DataType::kNumberTypeFloat32, {2, 2, 3},
|
||||
reinterpret_cast<void *>(input_data.data()), 12 * sizeof(float));
|
||||
mindspore::MSTensor input2("input", mindspore::DataType::kNumberTypeInt32, {3},
|
||||
reinterpret_cast<void *>(input_data2.data()), 3 * sizeof(int32_t));
|
||||
inputs.emplace_back(input);
|
||||
inputs.emplace_back(input2);
|
||||
|
||||
ASSERT_EQ(kernel_executor_->Build(op, inputs, context_), mindspore::kSuccess);
|
||||
ASSERT_EQ(kernel_executor_->Execute(inputs, &outputs), mindspore::kSuccess);
|
||||
float correct[] = {1, 4, 2, 5, 3, 6, 7, 10, 8, 11, 9, 12};
|
||||
ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs[0].MutableData()), correct, outputs[0].ElementNum(),
|
||||
0.0001));
|
||||
}
|
||||
} // namespace mindspore
|
||||
|
|
Loading…
Reference in New Issue