MSLite, GPU and Ascend bugfix
This commit is contained in:
parent
550ff897c2
commit
36366ff80c
|
@ -68,6 +68,9 @@ static const char *const kGPUContext = "gpu_context";
|
|||
static const char *const kInputShape = "input_shape";
|
||||
static const char *const kDynamicDims = "dynamic_dims";
|
||||
static const char *const kOptimizeDims = "opt_dims";
|
||||
static const char *const kPrecisionMode = "precision_mode";
|
||||
static const char *const kDumpOps = "dump_ops";
|
||||
static const char *const kDumpDir = "dump_dir";
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
||||
|
||||
|
|
|
@ -239,6 +239,10 @@ bool ProfileParser::ParseDynamicDims(const std::string &dynamic_dims_str, Profil
|
|||
}
|
||||
|
||||
bool ProfileParser::ParseOptDims(const std::string &opt_dims_str, ProfileConfigs *profile_configs_ptr) {
|
||||
if (opt_dims_str.empty()) {
|
||||
MS_LOG(ERROR) << "The option " << lite::kOptimizeDims << " cannot be empty in [gpu_context]";
|
||||
return false;
|
||||
}
|
||||
auto &profile_configs = *profile_configs_ptr;
|
||||
auto inputs_of_str = Split(opt_dims_str, ";");
|
||||
if (inputs_of_str.size() != profile_configs.input_infos.size()) {
|
||||
|
@ -300,13 +304,9 @@ bool ProfileParser::Parse(const std::map<std::string, std::string> &context, boo
|
|||
return false;
|
||||
}
|
||||
auto &profile_configs = *profile_configs_ptr;
|
||||
auto get_item = [&context](const std::string &key) -> std::string {
|
||||
auto it = context.find(key);
|
||||
return it != context.end() ? it->second : "";
|
||||
};
|
||||
auto input_shapes = get_item(lite::kInputShape);
|
||||
auto dynamic_dims = get_item(lite::kDynamicDims);
|
||||
auto opt_dims = get_item(lite::kOptimizeDims);
|
||||
auto input_shapes = GetOption(context, lite::kInputShape, "");
|
||||
auto dynamic_dims = GetOption(context, lite::kDynamicDims, "");
|
||||
auto opt_dims = GetOption(context, lite::kOptimizeDims, "");
|
||||
if (input_shapes.empty() && dynamic_dims.empty() && opt_dims.empty()) {
|
||||
MS_LOG(INFO) << "Do not found config of input range('" << lite::kInputShape << "')";
|
||||
return true;
|
||||
|
@ -362,7 +362,7 @@ bool ProfileParser::ReorderByInputNames(const std::vector<std::string> &input_na
|
|||
auto &profiles = profile_configs->profiles;
|
||||
|
||||
for (size_t input_index = 0; input_index < input_names.size(); input_index++) {
|
||||
auto input_name = input_names[input_index];
|
||||
const auto &input_name = input_names[input_index];
|
||||
size_t i = 0;
|
||||
for (; i < input_infos.size(); i++) {
|
||||
if (input_infos[i].name == input_name) {
|
||||
|
@ -381,4 +381,13 @@ bool ProfileParser::ReorderByInputNames(const std::vector<std::string> &input_na
|
|||
*profile_configs = new_profile_configs;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ProfileParser::GetOption(const std::map<std::string, std::string> &context, const std::string &option,
|
||||
const std::string &default_val) {
|
||||
auto it = context.find(option);
|
||||
if (it == context.end()) {
|
||||
return default_val;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -54,13 +54,17 @@ class MS_API ProfileParser {
|
|||
|
||||
static bool ReorderByInputNames(const std::vector<std::string> &input_names, ProfileConfigs *profile_configs);
|
||||
|
||||
static std::string GetOption(const std::map<std::string, std::string> &context, const std::string &option,
|
||||
const std::string &default_val = "");
|
||||
|
||||
static bool StrToInt64(const std::string &str, int64_t *val);
|
||||
static std::vector<std::string> Split(const std::string &str, const std::string &delim);
|
||||
|
||||
private:
|
||||
static bool ParseOptDims(const std::string &opt_dims_str, ProfileConfigs *profile_configs);
|
||||
static bool ParseDynamicDims(const std::string &dynamic_dims_str, ProfileConfigs *profile_configs);
|
||||
static bool ParseInputShape(const std::string &input_shapes_str, ProfileConfigs *profile_configs);
|
||||
|
||||
static bool StrToInt64(const std::string &str, int64_t *val);
|
||||
static std::vector<std::string> Split(const std::string &str, const std::string &delim);
|
||||
static bool ParseShapeStr(const std::vector<std::string> &str_dims, ShapeVector *shape_ptr);
|
||||
static bool ParseRangeStr(const std::string &range_str, int64_t *min_ptr, int64_t *max_ptr);
|
||||
static bool ParseOptDimStr(const std::string &opt_dim_str, int64_t *opt_ptr);
|
||||
|
|
|
@ -72,7 +72,6 @@ file(GLOB TENSORRT_RUNTIME_SRC LIST_DIRECTORIES false
|
|||
# )
|
||||
|
||||
link_libraries(${CUDA_LIB_PATH}/libcudnn.so)
|
||||
link_libraries(${CUDA_LIB_PATH}/libnvrtc.so)
|
||||
link_libraries(${CUDA_LIB_PATH}/libcublasLt.so)
|
||||
|
||||
add_library(libcudart SHARED IMPORTED)
|
||||
|
|
|
@ -74,7 +74,11 @@ int PoolTensorRT::AddInnerOp(TensorRTContext *ctx) {
|
|||
MS_LOG(ERROR) << "addPoolingNd failed for TensorRT.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
AddParams(pooling_layer);
|
||||
ret = AddParams(pooling_layer);
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "AddParams failed for : " << op_name_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
pooling_layer->setName(op_name_.c_str());
|
||||
this->layer_ = pooling_layer;
|
||||
}
|
||||
|
@ -174,22 +178,33 @@ int PoolTensorRT::ParseParams(TensorRTContext *ctx) {
|
|||
return RET_OK;
|
||||
}
|
||||
|
||||
void PoolTensorRT::AddParams(nvinfer1::IPoolingLayer *pooling_layer) {
|
||||
int PoolTensorRT::AddParams(nvinfer1::IPoolingLayer *pooling_layer) {
|
||||
nvinfer1::Dims stride_dims = ConvertCudaDims(stride_);
|
||||
if (stride_dims.nbDims == -1) {
|
||||
MS_LOG(ERROR) << "ConvertCudaDims failed for " << op_name_;
|
||||
return;
|
||||
return RET_ERROR;
|
||||
}
|
||||
pooling_layer->setStrideNd(stride_dims);
|
||||
if (pad_mode_ == PadMode::SAME) {
|
||||
pooling_layer->setPaddingMode(nvinfer1::PaddingMode::kSAME_UPPER);
|
||||
} else {
|
||||
nvinfer1::Dims dims{};
|
||||
dims.nbDims = DIMENSION_2D;
|
||||
dims.d[0] = padding_[0];
|
||||
dims.d[1] = padding_[DIMENSION_2D];
|
||||
pooling_layer->setPaddingNd(dims);
|
||||
if (padding_.size() != DIMENSION_4D) {
|
||||
MS_LOG(ERROR) << "Invalid padding " << padding_ << ", op: " << op_name_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
nvinfer1::Dims pre_dims{};
|
||||
pre_dims.nbDims = DIMENSION_2D;
|
||||
pre_dims.d[0] = padding_[kDim0];
|
||||
pre_dims.d[1] = padding_[kDim2];
|
||||
pooling_layer->setPrePadding(pre_dims);
|
||||
|
||||
nvinfer1::Dims post_dims{};
|
||||
post_dims.nbDims = DIMENSION_2D;
|
||||
post_dims.d[0] = padding_[kDim1];
|
||||
post_dims.d[1] = padding_[kDim3];
|
||||
pooling_layer->setPostPadding(post_dims);
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
REGISTER_TENSORRT_CREATOR(ops::kNameAvgPoolFusion, PoolTensorRT)
|
||||
REGISTER_TENSORRT_CREATOR(ops::kNameMaxPoolFusion, PoolTensorRT)
|
||||
|
|
|
@ -36,7 +36,7 @@ class PoolTensorRT : public TensorRTOp {
|
|||
private:
|
||||
int ParseParams(TensorRTContext *ctx);
|
||||
|
||||
void AddParams(nvinfer1::IPoolingLayer *pooling_layer);
|
||||
int AddParams(nvinfer1::IPoolingLayer *pooling_layer);
|
||||
|
||||
std::vector<int64_t> kernel_size_;
|
||||
|
||||
|
|
|
@ -35,16 +35,26 @@ int ShuffleTensorRT::IsSupport(const BaseOperatorPtr &base_operator, const std::
|
|||
return RET_ERROR;
|
||||
}
|
||||
} else if (type_ == ops::kNameSqueeze) {
|
||||
if (in_tensors.size() != 1) {
|
||||
constexpr size_t input_count_without_constant = 1;
|
||||
constexpr size_t input_count_with_constant = 2;
|
||||
if (in_tensors_.size() == input_count_without_constant) {
|
||||
auto squeeze_op = AsOps<ops::Squeeze>();
|
||||
if (squeeze_op == nullptr) {
|
||||
MS_LOG(ERROR) << "SqueezeOp convert failed";
|
||||
return RET_ERROR;
|
||||
}
|
||||
param_axis_ = squeeze_op->get_axis();
|
||||
} else if (in_tensors_.size() == input_count_with_constant) {
|
||||
if (!in_tensors_[1].IsConst()) {
|
||||
MS_LOG(ERROR) << "Expect input 1 to be const when input size is 2, type: " << type_ << ", op: " << op_name_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto axis = ConvertTensorAsIntVector(in_tensors_[1]);
|
||||
std::copy(axis.begin(), axis.end(), std::back_inserter(param_axis_));
|
||||
} else {
|
||||
MS_LOG(ERROR) << "Unsupported in_tensors size " << in_tensors.size() << " of " << type_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto squeeze_op = AsOps<ops::Squeeze>();
|
||||
if (squeeze_op == nullptr) {
|
||||
MS_LOG(ERROR) << "SqueezeOp convert failed";
|
||||
return RET_ERROR;
|
||||
}
|
||||
param_axis_ = squeeze_op->get_axis();
|
||||
if (param_axis_.empty()) {
|
||||
MS_LOG(WARNING) << op_name_ << " is a full dim squeeze, don't support dynamic input shape.";
|
||||
dynamic_shape_params_.support_dynamic_ = false;
|
||||
|
@ -56,9 +66,6 @@ int ShuffleTensorRT::IsSupport(const BaseOperatorPtr &base_operator, const std::
|
|||
return RET_ERROR;
|
||||
}
|
||||
dynamic_shape_params_.support_hw_dynamic_ = false;
|
||||
// if (in_tensors[0].Shape()[0] != out_tensors[0].Shape()[0]) {
|
||||
// dynamic_shape_params_.support_dynamic_ = false;
|
||||
// }
|
||||
} else if (type_ == ops::kNameTranspose || type_ == ops::kNameExpandDims) {
|
||||
if (in_tensors.size() != INPUT_SIZE2) {
|
||||
MS_LOG(ERROR) << "PrimitiveType_Transpose Unsupported in_tensors size: " << in_tensors.size();
|
||||
|
|
|
@ -21,14 +21,15 @@
|
|||
#include "ops/strided_slice.h"
|
||||
|
||||
namespace mindspore::lite {
|
||||
nvinfer1::ITensor *StrideSliceTensorRT::GetDynamicSliceSize(TensorRTContext *ctx, nvinfer1::ITensor *input,
|
||||
int size_dim, int axis) {
|
||||
nvinfer1::ITensor *StrideSliceTensorRT::GetDynamicAxisSliceSize(TensorRTContext *ctx, nvinfer1::ITensor *input,
|
||||
int size_dim, int axis,
|
||||
nvinfer1::ITensor *size_tensor) {
|
||||
auto in_tensor_shape = ctx->network()->addShape(*input)->getOutput(0);
|
||||
if (in_tensor_shape == nullptr) {
|
||||
MS_LOG(ERROR) << "add shape layer of input failed!";
|
||||
return nullptr;
|
||||
}
|
||||
auto len_tensor = ctx->ConvertTo1DTensor(static_cast<int>(size_dim));
|
||||
auto len_tensor = (size_tensor == nullptr ? ctx->ConvertTo1DTensor(static_cast<int>(size_dim)) : size_tensor);
|
||||
if (len_tensor == nullptr) {
|
||||
MS_LOG(ERROR) << "convert 1d tensor failed!";
|
||||
return nullptr;
|
||||
|
@ -62,6 +63,35 @@ nvinfer1::ITensor *StrideSliceTensorRT::GetDynamicSliceSize(TensorRTContext *ctx
|
|||
return gather_layer->getOutput(0);
|
||||
}
|
||||
|
||||
nvinfer1::ITensor *StrideSliceTensorRT::GetDynamicSliceSize(TensorRTContext *ctx, nvinfer1::ITensor *input,
|
||||
const nvinfer1::Dims &size_dims) {
|
||||
auto in_tensor_shape = ctx->network()->addShape(*input)->getOutput(0);
|
||||
if (in_tensor_shape == nullptr) {
|
||||
MS_LOG(ERROR) << "add shape layer of input failed!";
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<int> is_dynamic;
|
||||
std::vector<int> is_fix;
|
||||
std::vector<int> size_vec;
|
||||
for (int i = 0; i != size_dims.nbDims; ++i) {
|
||||
is_dynamic.push_back(size_dims.d[i] < 0);
|
||||
is_fix.push_back(size_dims.d[i] >= 0);
|
||||
size_vec.push_back(size_dims.d[i]);
|
||||
}
|
||||
auto is_dynamic_tensor = ctx->ConvertTo1DTensor(is_dynamic);
|
||||
auto is_fix_tensor = ctx->ConvertTo1DTensor(is_fix);
|
||||
auto size_tensor = ctx->ConvertTo1DTensor(size_vec);
|
||||
|
||||
auto fix_tensor =
|
||||
ctx->network()->addElementWise(*is_fix_tensor, *size_tensor, nvinfer1::ElementWiseOperation::kPROD)->getOutput(0);
|
||||
auto dynamic_tensor = ctx->network()
|
||||
->addElementWise(*is_dynamic_tensor, *in_tensor_shape, nvinfer1::ElementWiseOperation::kPROD)
|
||||
->getOutput(0);
|
||||
size_tensor =
|
||||
ctx->network()->addElementWise(*dynamic_tensor, *fix_tensor, nvinfer1::ElementWiseOperation::kSUM)->getOutput(0);
|
||||
return size_tensor;
|
||||
}
|
||||
|
||||
int StrideSliceTensorRT::IsSupport(const BaseOperatorPtr &base_operator, const std::vector<TensorInfo> &in_tensors,
|
||||
const std::vector<TensorInfo> &out_tensors) {
|
||||
if (in_tensors.size() < HAS_AXIS - 1) {
|
||||
|
@ -72,111 +102,95 @@ int StrideSliceTensorRT::IsSupport(const BaseOperatorPtr &base_operator, const s
|
|||
MS_LOG(ERROR) << "Unsupported output tensor size, size is " << out_tensors.size();
|
||||
return RET_ERROR;
|
||||
}
|
||||
if (!in_tensors.at(BEGINS_INDEX).IsConst() || !in_tensors.at(ENDS_INDEX).IsConst()) {
|
||||
if (!in_tensors.at(BEGINS_INDEX).IsConst()) {
|
||||
MS_LOG(ERROR) << "invalid input tensor for: " << op_name_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
bool StrideSliceTensorRT::GetConstInputValue(int *axis_val, int *start_val, int *end_val, int *stride_val) {
|
||||
int StrideSliceTensorRT::ComputeSliceDims(TensorRTContext *ctx, ITensorHelper *slice_input) {
|
||||
auto op = AsOps<ops::StridedSlice>();
|
||||
shrink_axis_ = op->get_shrink_axis_mask();
|
||||
size_t start_mask = op->get_begin_mask();
|
||||
size_t end_mask = op->get_end_mask();
|
||||
|
||||
const auto &begin = in_tensors_.at(BEGINS_INDEX);
|
||||
const auto &stride = in_tensors_.back();
|
||||
const auto &end = in_tensors_.at(ENDS_INDEX);
|
||||
|
||||
auto input_dims = slice_input->trt_tensor_->getDimensions();
|
||||
|
||||
int64_t axis_index = in_tensors_.size() == HAS_AXIS ? AXIS_INDEX : -1;
|
||||
const auto &begin = in_tensors_.at(BEGINS_INDEX);
|
||||
const auto &stride = in_tensors_.back();
|
||||
const auto &end = in_tensors_.at(ENDS_INDEX);
|
||||
|
||||
if (begin.ElementNum() != 1 || end.ElementNum() != 1 || stride.ElementNum() != 1) {
|
||||
MS_LOG(ERROR)
|
||||
<< "Only support element number of begin, end and stride to be 1 when this number < input dims number, op: "
|
||||
<< op_name_;
|
||||
return false;
|
||||
}
|
||||
*axis_val = 0;
|
||||
if (axis_index != -1) {
|
||||
auto axis_vec = ConvertTensorAsIntVector(in_tensors_[axis_index]);
|
||||
if (axis_vec.size() != 1) {
|
||||
MS_LOG(ERROR) << "Failed to get axis input, node: " << op_name_ << ", axis count: " << axis_vec.size();
|
||||
return false;
|
||||
if (begin.ElementNum() == slice_input->trt_tensor_->getDimensions().nbDims) {
|
||||
start_dims_ = lite::ConvertCudaDims(begin.Data(), begin.ElementNum());
|
||||
auto end_dims = lite::ConvertCudaDims(end.Data(), end.ElementNum());
|
||||
size_dims_.nbDims = input_dims.nbDims;
|
||||
for (int i = 0; i < size_dims_.nbDims; i++) {
|
||||
size_t mask = 1 << i;
|
||||
start_dims_.d[i] = ((start_mask & mask) == 0 ? start_dims_.d[i] : 0);
|
||||
if (!end.IsConst()) {
|
||||
continue;
|
||||
}
|
||||
end_dims.d[i] = ((end_mask & mask) == 0 ? end_dims.d[i] : slice_input->trt_tensor_->getDimensions().d[i]);
|
||||
size_dims_.d[i] = end_dims.d[i] - start_dims_.d[i];
|
||||
}
|
||||
*axis_val = axis_vec[0];
|
||||
}
|
||||
auto start_vec = ConvertTensorAsIntVector(begin);
|
||||
auto end_vec = ConvertTensorAsIntVector(end);
|
||||
auto stride_vec = ConvertTensorAsIntVector(stride);
|
||||
if (start_vec.size() != 1 || end_vec.size() != 1 || stride_vec.size() != 1) {
|
||||
MS_LOG(ERROR) << "Failed to get start, end or stride input, node: " << op_name_;
|
||||
return {};
|
||||
}
|
||||
*start_val = start_vec[0];
|
||||
*end_val = end_vec[0];
|
||||
*stride_val = stride_vec[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
nvinfer1::ILayer *StrideSliceTensorRT::MakeLayer(TensorRTContext *ctx, const ITensorHelper &slice_input) {
|
||||
const auto &begin = in_tensors_.at(BEGINS_INDEX);
|
||||
const auto &stride = in_tensors_.back();
|
||||
const auto &end = in_tensors_.at(ENDS_INDEX);
|
||||
|
||||
auto input_dims = slice_input.trt_tensor_->getDimensions();
|
||||
if (input_dims.nbDims <= 0) {
|
||||
MS_LOG_ERROR << "Not support input dims to be dynamic, dim number " << input_dims.nbDims;
|
||||
return nullptr;
|
||||
}
|
||||
nvinfer1::Dims start_dims{input_dims};
|
||||
nvinfer1::Dims size_dims{input_dims};
|
||||
nvinfer1::Dims stride_dims{input_dims};
|
||||
|
||||
nvinfer1::ITensor *size_tensor = nullptr;
|
||||
if (begin.ElementNum() == input_dims.nbDims) {
|
||||
start_dims = lite::ConvertCudaDims(begin);
|
||||
auto end_dims = lite::ConvertCudaDims(end);
|
||||
for (int i = 0; i < size_dims.nbDims; i++) {
|
||||
size_dims.d[i] = end_dims.d[i] - start_dims.d[i];
|
||||
stride_dims_ = lite::ConvertCudaDims(stride.Data(), stride.ElementNum());
|
||||
if (IsDynamicInput(ctx, 0)) {
|
||||
size_tensor_ = GetDynamicSliceSize(ctx, slice_input->trt_tensor_, size_dims_);
|
||||
size_dims_ = nvinfer1::Dims{-1};
|
||||
}
|
||||
stride_dims = lite::ConvertCudaDims(stride);
|
||||
} else {
|
||||
int axis_value = 0;
|
||||
int start_value = 0;
|
||||
int end_value = 0;
|
||||
int stride_value = 0;
|
||||
if (!GetConstInputValue(&axis_value, &start_value, &end_value, &stride_value)) {
|
||||
return nullptr;
|
||||
if (axis_index == -1 || in_tensors_.at(axis_index).ElementNum() != 1) {
|
||||
MS_LOG(ERROR) << "invalid input params for " << op_name_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
std::fill(start_dims.d, start_dims.d + start_dims.nbDims, 0);
|
||||
std::fill(stride_dims.d, stride_dims.d + stride_dims.nbDims, 1);
|
||||
size_dims = slice_input.trt_tensor_->getDimensions();
|
||||
int axis_value = *(static_cast<const int *>(in_tensors_.at(axis_index).Data()));
|
||||
if (axis_value < 0) {
|
||||
axis_value += input_dims.nbDims;
|
||||
}
|
||||
int start_value = *(static_cast<const int *>(begin.Data()));
|
||||
int stride_value = *(static_cast<const int *>(stride.Data()));
|
||||
start_dims_.nbDims = input_dims.nbDims;
|
||||
std::fill(start_dims_.d, start_dims_.d + start_dims_.nbDims, 0);
|
||||
stride_dims_.nbDims = input_dims.nbDims;
|
||||
std::fill(stride_dims_.d, stride_dims_.d + stride_dims_.nbDims, 1);
|
||||
size_dims_ = slice_input->trt_tensor_->getDimensions();
|
||||
if (start_value < 0) {
|
||||
start_value = input_dims.d[axis_value] + start_value;
|
||||
}
|
||||
for (int i = 0; i < start_dims.nbDims; i++) {
|
||||
for (int i = 0; i < start_dims_.nbDims; i++) {
|
||||
if (i == axis_value) {
|
||||
start_dims.d[i] = start_value;
|
||||
stride_dims.d[i] = stride_value;
|
||||
if (end_value >= 0) {
|
||||
size_dims.d[i] = std::min(end_value, input_dims.d[i]) - start_dims.d[i];
|
||||
} else if (end_value >= -input_dims.d[i]) {
|
||||
size_dims.d[i] = end_value + input_dims.d[i] - start_dims.d[i];
|
||||
} else {
|
||||
size_dims.d[i] = input_dims.d[i];
|
||||
start_dims_.d[i] = start_value;
|
||||
stride_dims_.d[i] = stride_value;
|
||||
if (end.IsConst()) {
|
||||
int end_value = *(static_cast<const int *>(end.Data()));
|
||||
if (end_value >= 0) {
|
||||
size_dims_.d[i] = std::min(end_value, input_dims.d[i]) - start_dims_.d[i];
|
||||
} else if (end_value >= -input_dims.d[i]) {
|
||||
size_dims_.d[i] = end_value + input_dims.d[i] - start_dims_.d[i];
|
||||
} else {
|
||||
size_dims_.d[i] = input_dims.d[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (IsDynamicInput(ctx, 0)) {
|
||||
size_tensor = GetDynamicSliceSize(ctx, slice_input.trt_tensor_, size_dims.d[axis_value], axis_value);
|
||||
size_dims = nvinfer1::Dims{-1};
|
||||
size_tensor_ =
|
||||
GetDynamicAxisSliceSize(ctx, slice_input->trt_tensor_, size_dims_.d[axis_value], axis_value, nullptr);
|
||||
size_dims_ = nvinfer1::Dims{-1};
|
||||
}
|
||||
if (!end.IsConst()) {
|
||||
auto start_tensor = ctx->ConvertTo1DTensor(start_value);
|
||||
auto len_tensor =
|
||||
ctx->network()
|
||||
->addElementWise(*input(ctx, INPUT_SIZE2).trt_tensor_, *start_tensor, nvinfer1::ElementWiseOperation::kSUB)
|
||||
->getOutput(0);
|
||||
size_tensor_ = GetDynamicAxisSliceSize(ctx, slice_input->trt_tensor_, -1, axis_value, len_tensor);
|
||||
size_dims_ = nvinfer1::Dims{-1};
|
||||
}
|
||||
}
|
||||
nvinfer1::ISliceLayer *slice_layer =
|
||||
ctx->network()->addSlice(*slice_input.trt_tensor_, start_dims, size_dims, stride_dims);
|
||||
if (slice_layer == nullptr) {
|
||||
MS_LOG(ERROR) << "add Slice op failed for TensorRT: " << op_name_;
|
||||
return nullptr;
|
||||
}
|
||||
if (size_tensor != nullptr) {
|
||||
slice_layer->setInput(INPUT_SIZE2, *size_tensor);
|
||||
}
|
||||
return slice_layer;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int StrideSliceTensorRT::AddInnerOp(TensorRTContext *ctx) {
|
||||
|
@ -194,17 +208,23 @@ int StrideSliceTensorRT::AddInnerOp(TensorRTContext *ctx) {
|
|||
return RET_ERROR;
|
||||
}
|
||||
|
||||
auto slice_layer = MakeLayer(ctx, slice_input);
|
||||
if (slice_layer == nullptr) {
|
||||
if (ComputeSliceDims(ctx, &slice_input) != RET_OK) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
nvinfer1::ISliceLayer *slice_layer =
|
||||
ctx->network()->addSlice(*slice_input.trt_tensor_, start_dims_, size_dims_, stride_dims_);
|
||||
if (slice_layer == nullptr) {
|
||||
MS_LOG(ERROR) << "add Slice op failed for TensorRT: " << op_name_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
if (size_tensor_ != nullptr) {
|
||||
slice_layer->setInput(INPUT_SIZE2, *size_tensor_);
|
||||
}
|
||||
this->layer_ = slice_layer;
|
||||
slice_layer->setName(op_name_.c_str());
|
||||
nvinfer1::ITensor *out_tensor = slice_layer->getOutput(0);
|
||||
auto shape = ConvertMSShape(out_tensor->getDimensions());
|
||||
bool rank_0 = false;
|
||||
|
||||
shrink_axis_ = AsOps<ops::StridedSlice>()->get_shrink_axis_mask();
|
||||
if (shrink_axis_ != 0) {
|
||||
for (int i = SizeToInt(shape.size()) - 1; i >= 0; --i) {
|
||||
int mask = 1 << i;
|
||||
|
|
|
@ -40,10 +40,18 @@ class StrideSliceTensorRT : public TensorRTOp {
|
|||
const std::vector<TensorInfo> &out_tensors) override;
|
||||
|
||||
private:
|
||||
nvinfer1::ITensor *GetDynamicSliceSize(TensorRTContext *ctx, nvinfer1::ITensor *input, int, int);
|
||||
nvinfer1::ILayer *MakeLayer(TensorRTContext *ctx, const ITensorHelper &slice_input);
|
||||
bool GetConstInputValue(int *axis, int *start, int *end, int *stride);
|
||||
nvinfer1::ITensor *GetDynamicSliceSize(TensorRTContext *ctx, nvinfer1::ITensor *input,
|
||||
const nvinfer1::Dims &size_dims);
|
||||
nvinfer1::ITensor *GetDynamicAxisSliceSize(TensorRTContext *ctx, nvinfer1::ITensor *input, int size_dim, int axis,
|
||||
nvinfer1::ITensor *size_tensor);
|
||||
int ComputeSliceDims(TensorRTContext *ctx, ITensorHelper *slice_input);
|
||||
size_t shrink_axis_;
|
||||
size_t start_axis_;
|
||||
size_t end_axis_;
|
||||
nvinfer1::Dims start_dims_;
|
||||
nvinfer1::Dims size_dims_;
|
||||
nvinfer1::Dims stride_dims_;
|
||||
nvinfer1::ITensor *size_tensor_{nullptr};
|
||||
};
|
||||
} // namespace mindspore::lite
|
||||
#endif // MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_TENSORRT_OP_STRIDE_SLICE_TENSORRT_H_
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <string>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include "src/extendrt/delegate/delegate_utils.h"
|
||||
#include "ccsrc/kernel/common_utils.h"
|
||||
#include "ccsrc/backend/common/optimizer/helper.h"
|
||||
|
@ -356,6 +357,23 @@ int TensorRTExecutor::ParseOptimizationProfile() {
|
|||
return RET_FAILED;
|
||||
}
|
||||
trt_profile_configs_ = profile_configs;
|
||||
auto precision_mode = ProfileParser::GetOption(gpu_context, lite::kPrecisionMode, "");
|
||||
if (precision_mode == "force_fp16") {
|
||||
device_info_->SetEnableFP16(true);
|
||||
MS_LOG(INFO) << "Set precision mode to fp16 by config file";
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int TensorRTExecutor::ParseDumpOptions(const std::map<std::string, std::string> &gpu_context) {
|
||||
auto dump_ops_str = ProfileParser::GetOption(gpu_context, lite::kDumpOps, "");
|
||||
if (!dump_ops_str.empty()) {
|
||||
dump_ops_ = ProfileParser::Split(dump_ops_str, ";");
|
||||
dump_dir_ = ProfileParser::GetOption(gpu_context, lite::kDumpDir, "");
|
||||
if (dump_dir_.empty()) {
|
||||
dump_dir_ = ".";
|
||||
}
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -397,12 +415,17 @@ Status TensorRTExecutor::BuildSubGraph(const KernelGraphPtr &kernel_graph) {
|
|||
}
|
||||
tensorrt_op->SetRuntime(this->runtime_);
|
||||
tensorrt_ops.push_back(tensorrt_op);
|
||||
if (!dump_ops_.empty() && std::find(dump_ops_.begin(), dump_ops_.end(), node_name) != dump_ops_.end()) {
|
||||
std::copy(output_tensors.begin(), output_tensors.end(), std::back_inserter(dump_outputs_));
|
||||
}
|
||||
}
|
||||
status = GetModelOutputsInfo(kernel_graph, &tensor_info_list, &outputs_);
|
||||
if (status != kSuccess) {
|
||||
return status;
|
||||
}
|
||||
tensorrt_graph_ = CreateTensorRTGraph(tensorrt_ops, kernel_graph, tensorrt_subgraph_index, inputs_, outputs_);
|
||||
std::vector<TensorInfo> trt_outputs = outputs_;
|
||||
std::copy(dump_outputs_.begin(), dump_outputs_.end(), std::back_inserter(trt_outputs));
|
||||
tensorrt_graph_ = CreateTensorRTGraph(tensorrt_ops, kernel_graph, tensorrt_subgraph_index, inputs_, trt_outputs);
|
||||
if (!tensorrt_graph_) {
|
||||
MS_LOG(ERROR) << "Create tensorrt graph failed";
|
||||
return mindspore::kLiteError;
|
||||
|
@ -513,15 +536,62 @@ bool TensorRTExecutor::RunGraph(const FuncGraphPtr &graph, const std::vector<ten
|
|||
MS_LOG(ERROR) << "Graph inputs size " << inputs_.size() << " != execute outputs size " << inputs.size();
|
||||
return false;
|
||||
}
|
||||
if (!outputs->empty() && outputs_.size() != outputs->size()) {
|
||||
MS_LOG(ERROR) << "Graph outputs size " << inputs_.size() << " != expected outputs size " << outputs->size();
|
||||
return false;
|
||||
}
|
||||
if (tensorrt_graph_ == nullptr) {
|
||||
MS_LOG(ERROR) << "TensorRT subgraph is nullptr.";
|
||||
return false;
|
||||
}
|
||||
return tensorrt_graph_->Execute(inputs, outputs) == RET_OK;
|
||||
if (dump_outputs_.empty()) {
|
||||
if (!outputs->empty() && outputs_.size() != outputs->size()) {
|
||||
MS_LOG(ERROR) << "Graph outputs size " << inputs_.size() << " != expected outputs size " << outputs->size();
|
||||
return false;
|
||||
}
|
||||
return tensorrt_graph_->Execute(inputs, outputs) == RET_OK;
|
||||
}
|
||||
|
||||
if (!outputs->empty()) {
|
||||
MS_LOG(ERROR) << "Cannot has graph outputs when dump op";
|
||||
return false;
|
||||
}
|
||||
std::vector<tensor::Tensor> trt_outputs;
|
||||
if (tensorrt_graph_->Execute(inputs, &trt_outputs) != RET_OK) {
|
||||
return false;
|
||||
}
|
||||
if (trt_outputs.size() != outputs_.size() + dump_outputs_.size()) {
|
||||
MS_LOG(ERROR) << "TensorRT Graph outputs size " << trt_outputs.size() << " != graph outputs size "
|
||||
<< outputs_.size() << " + dump output size " << dump_outputs_.size();
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < outputs_.size(); i++) {
|
||||
outputs->push_back(trt_outputs[i]);
|
||||
}
|
||||
if (!has_dumped_) {
|
||||
has_dumped_ = true;
|
||||
auto dump_tensor = [this](const std::string &file_name, const tensor::Tensor &tensor) {
|
||||
std::string new_file = file_name;
|
||||
for (size_t i = 0; i < new_file.size(); i++) {
|
||||
if (new_file[i] == '/' || new_file[i] == '\\') {
|
||||
new_file[i] = '_';
|
||||
}
|
||||
}
|
||||
std::ofstream fp(dump_dir_ + "/" + new_file, std::ofstream::binary);
|
||||
if (!fp.is_open()) {
|
||||
MS_LOG(WARNING) << "Failed to open file " << dump_dir_ + "/" + file_name;
|
||||
return;
|
||||
}
|
||||
fp.write(reinterpret_cast<const char *>(tensor.data_c()), tensor.Size());
|
||||
};
|
||||
for (size_t i = 0; i < inputs.size(); i++) {
|
||||
dump_tensor("input_" + std::to_string(i) + ".bin", inputs[i]);
|
||||
}
|
||||
for (size_t i = 0; i < outputs->size(); i++) {
|
||||
dump_tensor("output_" + std::to_string(i) + ".bin", (*outputs)[i]);
|
||||
}
|
||||
for (size_t i = outputs_.size(); i < trt_outputs.size(); i++) {
|
||||
auto tensor_info = dump_outputs_[i - outputs_.size()];
|
||||
dump_tensor(tensor_info.Name() + ".bin", trt_outputs[i]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TensorRTExecutor::Resize(const FuncGraphPtr &, const std::vector<tensor::Tensor> &inputs,
|
||||
|
|
|
@ -72,6 +72,7 @@ class TensorRTExecutor : public LiteGraphExecutor {
|
|||
const KernelGraphPtr &graph, int index,
|
||||
const std::vector<TensorInfo> &inputs,
|
||||
const std::vector<TensorInfo> &outputs);
|
||||
int ParseDumpOptions(const std::map<std::string, std::string> &gpu_context);
|
||||
|
||||
std::shared_ptr<mindspore::Context> context_{nullptr};
|
||||
ConfigInfos config_infos_;
|
||||
|
@ -94,6 +95,10 @@ class TensorRTExecutor : public LiteGraphExecutor {
|
|||
std::shared_ptr<TensorRTSubGraph> tensorrt_graph_ = nullptr;
|
||||
std::vector<TensorInfo> inputs_;
|
||||
std::vector<TensorInfo> outputs_;
|
||||
std::vector<TensorInfo> dump_outputs_;
|
||||
std::vector<std::string> dump_ops_;
|
||||
std::string dump_dir_;
|
||||
bool has_dumped_ = false;
|
||||
|
||||
KernelGraphUtilsPtr kernel_graph_utils_;
|
||||
};
|
||||
|
|
|
@ -560,6 +560,10 @@ int TensorRTSubGraph::Prepare() {
|
|||
for (auto &tensor : outputs_) {
|
||||
int max_index = GetProfileBindingIndex(tensor.Name(), profile_index_);
|
||||
auto out_dims = trt_context_->getBindingDimensions(max_index);
|
||||
if (out_dims.nbDims < 0) {
|
||||
MS_LOG(ERROR) << "Output dims number " << out_dims.nbDims << " cannot less than 0";
|
||||
return RET_ERROR;
|
||||
}
|
||||
int elem_num = std::accumulate(out_dims.d, out_dims.d + out_dims.nbDims, 1, std::multiplies<int>());
|
||||
DebugDims("out dims", out_dims);
|
||||
MS_LOG(INFO) << "Set output shape by tensorrt binding output";
|
||||
|
|
|
@ -115,7 +115,7 @@ int StrideSliceTensorRT::ComputeSliceDims(TensorRTContext *ctx, ITensorHelper *s
|
|||
|
||||
auto input_dims = slice_input->trt_tensor_->getDimensions();
|
||||
|
||||
size_t axis_index = in_tensors_.size() == HAS_AXIS ? AXIS_INDEX : -1;
|
||||
int64_t axis_index = in_tensors_.size() == HAS_AXIS ? AXIS_INDEX : -1;
|
||||
if (static_cast<size_t>(begin.ElementNum()) == slice_input->trt_tensor_->getDimensions().nbDims) {
|
||||
start_dims_ = lite::ConvertCudaDims(begin.Data().get(), begin.ElementNum());
|
||||
auto end_dims = lite::ConvertCudaDims(end.Data().get(), end.ElementNum());
|
||||
|
|
|
@ -43,6 +43,11 @@ int ReshapeBaseCPUKernel::Run() {
|
|||
CHECK_NULL_RETURN(in_tensor);
|
||||
auto out_tensor = out_tensors().front();
|
||||
CHECK_NULL_RETURN(out_tensor);
|
||||
auto in_shape = in_tensor->shape();
|
||||
// element number is 0, no need to copy data
|
||||
if (std::any_of(in_shape.begin(), in_shape.end(), [](auto dim) { return dim == 0; })) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
if (in_tensor->data_type() != out_tensor->data_type() || in_tensor->data() == nullptr ||
|
||||
in_tensor->Size() != out_tensor->Size()) {
|
||||
|
|
|
@ -60,7 +60,7 @@ int SparseToDenseCPUKernel::Prepare() {
|
|||
}
|
||||
|
||||
int SparseToDenseCPUKernel::ReSize() {
|
||||
if (in_tensors_.at(THIRD_INPUT)->data_type() != kNumberTypeFloat16 ||
|
||||
if (in_tensors_.at(THIRD_INPUT)->data_type() != kNumberTypeFloat16 &&
|
||||
in_tensors_.at(THIRD_INPUT)->data_type() != kNumberTypeFloat32) {
|
||||
MS_LOG(ERROR) << in_tensors_.at(THIRD_INPUT)->tensor_name() << " data type "
|
||||
<< in_tensors_.at(THIRD_INPUT)->data_type() << " is not support.";
|
||||
|
|
|
@ -98,6 +98,10 @@ STATUS Conv2dTransposeMapper::AdjustOutputPadding(const PrimitivePtr &dst_prim)
|
|||
output_padding[kDim4D] = val[1];
|
||||
}
|
||||
dst_prim->set_attr(ops::kOutputPaddings, MakeValue(output_padding));
|
||||
auto pad_list_value_ptr = dst_prim->GetAttr(ops::kPadList);
|
||||
if (!pad_list_value_ptr) {
|
||||
dst_prim->set_attr(ops::kPadList, MakeValue(std::vector<int64_t>{0, 0, 0, 0}));
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,29 +123,33 @@ void PrimitiveMapper::AdjustCaffePoolAttr(const std::string &src_prim_name, cons
|
|||
|
||||
void PrimitiveMapper::AdjustOnnxPoolAttr(const std::string &src_prim_name, const PrimitivePtr &dst_prim) const {
|
||||
auto pad_mode_val = dst_prim->GetAttr(ops::kPadMode);
|
||||
if (pad_mode_val == nullptr) {
|
||||
MS_LOG(INFO) << "There is no attr pad mode";
|
||||
return;
|
||||
}
|
||||
static std::map<int64_t, std::string> kPadModToStrMap = {
|
||||
{PadMode::PAD, "CALCULATED"},
|
||||
{PadMode::SAME, "SAME"},
|
||||
{PadMode::VALID, "VALID"},
|
||||
};
|
||||
auto pad_mode = GetValue<int64_t>(pad_mode_val);
|
||||
std::string padding_mode = "CALCULATED";
|
||||
if (kPadModToStrMap.find(pad_mode) != kPadModToStrMap.end()) {
|
||||
padding_mode = kPadModToStrMap[pad_mode];
|
||||
if (pad_mode_val) {
|
||||
auto pad_mode = GetValue<int64_t>(pad_mode_val);
|
||||
std::string padding_mode = "CALCULATED";
|
||||
if (kPadModToStrMap.find(pad_mode) != kPadModToStrMap.end()) {
|
||||
padding_mode = kPadModToStrMap[pad_mode];
|
||||
}
|
||||
if (src_prim_name == ops::kNameMaxPool && padding_mode == "CALCULATED") {
|
||||
padding_mode = "VALID";
|
||||
}
|
||||
std::string pad_mode_name = src_prim_name == acl::kNameMaxPoolV3 ? kNamePaddingMode : ops::kPadMode;
|
||||
dst_prim->AddAttr(pad_mode_name, MakeValue(padding_mode));
|
||||
} else {
|
||||
MS_LOG(INFO) << "There is no attr pad mode";
|
||||
}
|
||||
if (src_prim_name == ops::kNameMaxPool && padding_mode == "CALCULATED") {
|
||||
padding_mode = "VALID";
|
||||
}
|
||||
std::string pad_mode_name = src_prim_name == acl::kNameMaxPoolV3 ? kNamePaddingMode : ops::kPadMode;
|
||||
dst_prim->AddAttr(pad_mode_name, MakeValue(padding_mode));
|
||||
auto run_mode_val = dst_prim->GetAttr(ops::kRoundMode);
|
||||
int64_t run_mode = GetValue<int64_t>(run_mode_val);
|
||||
bool ceil_mode = run_mode == RoundMode::CEIL;
|
||||
dst_prim->AddAttr(kNameCeilMode, MakeValue(ceil_mode));
|
||||
if (run_mode_val) {
|
||||
int64_t run_mode = GetValue<int64_t>(run_mode_val);
|
||||
bool ceil_mode = run_mode == RoundMode::CEIL;
|
||||
dst_prim->AddAttr(kNameCeilMode, MakeValue(ceil_mode));
|
||||
} else {
|
||||
MS_LOG(INFO) << "There is no attr run mode";
|
||||
}
|
||||
}
|
||||
|
||||
STATUS PrimitiveMapper::AdjustPoolAttr(int fmk_type, const std::string &src_prim_name,
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
#endif
|
||||
#include "src/common/log_util.h"
|
||||
#include "src/common/string_utils.h"
|
||||
#include "src/common/config_infos.h"
|
||||
#include "tools/optimizer/fusion/groupnorm_fusion.h"
|
||||
#include "tools/optimizer/fusion/mul_reduce_fusion.h"
|
||||
#include "tools/optimizer/fusion/reshape_like_operator_ablation.h"
|
||||
|
@ -151,15 +152,14 @@ std::string TransInputShapesToString(const std::map<std::string, std::vector<int
|
|||
std::map<std::string, std::vector<int64_t>> TransStringToInputShapes(const std::string &shapes_str) {
|
||||
std::map<std::string, std::vector<int64_t>> shapes;
|
||||
auto shapes_pairs = lite::SplitStringToVector(shapes_str, ';');
|
||||
constexpr size_t name_shape_pair_size = 2;
|
||||
for (auto &kv_str : shapes_pairs) {
|
||||
auto kv_pair_strs = lite::SplitStringToVector(kv_str, ':');
|
||||
if (kv_pair_strs.size() != name_shape_pair_size) {
|
||||
auto pos = kv_str.rfind(':');
|
||||
if (pos == std::string::npos || pos + 1 == kv_str.size()) {
|
||||
MS_LOG_ERROR << "Invalid input shapes string: " << shapes_str;
|
||||
return {};
|
||||
}
|
||||
auto &name = kv_pair_strs[0];
|
||||
auto &shape_str = kv_pair_strs[1];
|
||||
auto name = kv_str.substr(0, pos);
|
||||
auto shape_str = kv_str.substr(pos + 1);
|
||||
auto shape_dims_str = lite::SplitStringToVector(shape_str, ',');
|
||||
std::vector<int64_t> shape;
|
||||
shape.reserve(shape_dims_str.size());
|
||||
|
@ -430,6 +430,17 @@ int AnfTransform::RunGraphPass(const FuncGraphPtr &old_graph, const std::shared_
|
|||
int AnfTransform::RunConvertPass(const FuncGraphPtr &old_graph, const std::shared_ptr<ConverterPara> ¶m) {
|
||||
if (param->device.find("Ascend") != std::string::npos) {
|
||||
if (opt::AclPassPlugin::GetInstance().HasPluginSo()) {
|
||||
auto is_static_input = param->aclModelOptionCfgParam.dynamic_image_size.empty() &&
|
||||
param->aclModelOptionCfgParam.dynamic_batch_size.empty();
|
||||
if (is_static_input) {
|
||||
auto status = RunConstFoldPass(old_graph, param);
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "Run const fold pass failed.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
} else {
|
||||
MS_LOG(INFO) << "Support dynamic input, not do const fold pass";
|
||||
}
|
||||
auto acl_pass_ptr = opt::AclPassPlugin::GetInstance().CreateAclPass(param);
|
||||
if (acl_pass_ptr == nullptr) {
|
||||
MS_LOG(ERROR) << "Acl pass ptr is nullptr.";
|
||||
|
|
|
@ -165,24 +165,33 @@ STATUS SetInt32TensorInfo(const tensorflow::TensorProto &tensor_proto, tensor::T
|
|||
MS_LOG(ERROR) << "new data failed";
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
if (tensor_proto.int_val_size() == 1) {
|
||||
for (int i = 0; i < shape_size; i++) {
|
||||
tensor_data[i] = tensor_proto.int_val(0);
|
||||
if (shape_size == 0) {
|
||||
return RET_OK;
|
||||
}
|
||||
if (tensor_proto.tensor_content().empty()) {
|
||||
const auto &origin_data = tensor_proto.int_val();
|
||||
if (tensor_proto.int_val_size() == 1) {
|
||||
for (int i = 0; i < shape_size; ++i) {
|
||||
tensor_data[i] = origin_data[0];
|
||||
}
|
||||
} else {
|
||||
MS_CHECK_GE(tensor_proto.int_val_size(), shape_size, RET_ERROR);
|
||||
for (int i = 0; i < shape_size; ++i) {
|
||||
tensor_data[i] = origin_data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (INT_MUL_OVERFLOW_THRESHOLD(shape_size, sizeof(int32_t), SIZE_MAX)) {
|
||||
MS_LOG(ERROR) << "data_size overflow.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
if (shape_size != 0 && tensor_proto.tensor_content().size() == shape_size * sizeof(int32_t)) {
|
||||
} else {
|
||||
if (INT_MUL_OVERFLOW_THRESHOLD(shape_size, sizeof(int32_t), SIZE_MAX)) {
|
||||
MS_LOG(ERROR) << "data_size overflow.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
MS_CHECK_GE(tensor_proto.tensor_content().size(), shape_size * sizeof(int32_t), RET_ERROR);
|
||||
const auto addr = reinterpret_cast<const int32_t *>(tensor_proto.tensor_content().data());
|
||||
if (::memcpy_s(tensor_data, (*tensor_info)->Size(), addr, shape_size * sizeof(int32_t)) != EOK) {
|
||||
MS_LOG(ERROR) << "memcpy_s failed";
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -203,14 +212,29 @@ STATUS SetInt64TensorInfo(const tensorflow::TensorProto &tensor_proto, tensor::T
|
|||
MS_LOG(ERROR) << "new data failed";
|
||||
return RET_ERROR;
|
||||
}
|
||||
if (tensor_proto.tensor_shape().dim_size() == 0) { // scalar
|
||||
if (shape_size == 0) {
|
||||
return RET_OK;
|
||||
}
|
||||
if (tensor_proto.tensor_content().empty()) {
|
||||
const auto &origin_data = tensor_proto.int64_val();
|
||||
for (int i = 0; i < tensor_proto.int64_val_size(); ++i) {
|
||||
if (origin_data[i] > static_cast<int64_t>(INT32_MAX) || origin_data[i] < static_cast<int64_t>(INT32_MIN)) {
|
||||
MS_LOG(ERROR) << "int64 data " << origin_data[i] << "too big to fit into int32";
|
||||
if (tensor_proto.int64_val_size() == 1) {
|
||||
auto dim_val = origin_data[0];
|
||||
if (dim_val > static_cast<int64_t>(INT32_MAX) || dim_val < static_cast<int64_t>(INT32_MIN)) {
|
||||
MS_LOG(ERROR) << "int64 data " << dim_val << "too big to fit into int32";
|
||||
return RET_ERROR;
|
||||
} else {
|
||||
tensor_data[i] = static_cast<int>(origin_data[i]);
|
||||
}
|
||||
for (int i = 0; i < shape_size; ++i) {
|
||||
tensor_data[i] = static_cast<int>(dim_val);
|
||||
}
|
||||
} else {
|
||||
MS_CHECK_GE(tensor_proto.int64_val_size(), shape_size, RET_ERROR);
|
||||
for (int i = 0; i < shape_size; ++i) {
|
||||
auto dim_val = origin_data[i];
|
||||
if (dim_val > static_cast<int64_t>(INT32_MAX) || dim_val < static_cast<int64_t>(INT32_MIN)) {
|
||||
MS_LOG(ERROR) << "int64 data " << dim_val << "too big to fit into int32";
|
||||
return RET_ERROR;
|
||||
}
|
||||
tensor_data[i] = static_cast<int>(dim_val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1007,7 +1031,7 @@ STATUS TFModelParser::ConvertOps(const tensorflow::NodeDef &node_def,
|
|||
MSLITE_CHECK_PTR(anf_node_map);
|
||||
STATUS status = RET_OK;
|
||||
const auto &op_type = node_def.op();
|
||||
if (op_type == "Identity" || op_type == "StopGradient") {
|
||||
if (op_type == "Identity" || op_type == "StopGradient" || op_type == "NoOp") {
|
||||
return RET_OK;
|
||||
} else if (op_type == "Placeholder" || op_type == "Const") {
|
||||
node_output_num_[node_def.name()] = 1;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* 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,
|
||||
* distributed under the License is distributed on an AS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tools/converter/parser/tf/tf_sparse_to_dense_parser.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "ops/sparse_to_dense.h"
|
||||
#include "nnacl/op_base.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
PrimitiveCPtr TfSparseToDenseParser::Parse(const tensorflow::NodeDef &tf_op,
|
||||
const std::map<string, const tensorflow::NodeDef *> &tf_node_map,
|
||||
std::vector<std::string> *inputs, int *output_size) {
|
||||
auto prim = std::make_unique<ops::SparseToDense>();
|
||||
MS_CHECK_TRUE_RET(prim != nullptr, nullptr);
|
||||
*output_size = 1;
|
||||
for (int i = 0; i < tf_op.input_size(); ++i) {
|
||||
if (AddOpInput(tf_op, i, inputs) != RET_OK) {
|
||||
MS_LOG(ERROR) << "add op input " << i << " failed";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return prim->GetPrim();
|
||||
}
|
||||
TFNodeRegistrar g_tfSparseToDenseParser("SparseToDense", new TfSparseToDenseParser());
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_LITE_TOOLS_CONVERTER_PARSER_TF_TF_SPARSE_TO_DENSE_PARSER_H_
|
||||
#define MINDSPORE_LITE_TOOLS_CONVERTER_PARSER_TF_TF_SPARSE_TO_DENSE_PARSER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "tools/converter/parser/tf/tf_node_parser.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
class TfSparseToDenseParser : public TFNodeParser {
|
||||
public:
|
||||
TfSparseToDenseParser() = default;
|
||||
~TfSparseToDenseParser() override = default;
|
||||
|
||||
PrimitiveCPtr Parse(const tensorflow::NodeDef &tf_op,
|
||||
const std::map<string, const tensorflow::NodeDef *> &tf_node_map,
|
||||
std::vector<std::string> *inputs, int *output_size) override;
|
||||
};
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_LITE_TOOLS_CONVERTER_PARSER_TF_TF_SPARSE_TO_DENSE_PARSER_H_
|
|
@ -38,6 +38,7 @@
|
|||
#include "ops/op_utils.h"
|
||||
#include "ops/custom.h"
|
||||
#include "include/common/utils/anfalgo.h"
|
||||
#include "tools/optimizer/common/format_utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace opt {
|
||||
|
@ -1091,6 +1092,62 @@ size_t GetOutputSize(const AnfNodePtr &anf_node) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
ShapeVector GetAnfNodeOutputShape(const AnfNodePtr &node, size_t output_idx) {
|
||||
if (node == nullptr) {
|
||||
MS_LOG(ERROR) << "anf_node is nullptr.";
|
||||
return {};
|
||||
}
|
||||
auto as_value_node = node->cast<ValueNodePtr>();
|
||||
if (as_value_node) {
|
||||
auto value = as_value_node->value();
|
||||
auto tensor = value->cast<tensor::TensorPtr>();
|
||||
if (tensor) {
|
||||
return tensor->shape_c();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
auto base_shape = node->Shape();
|
||||
if (base_shape == nullptr) {
|
||||
MS_LOG(INFO) << "Failed to get shape from node " << node->fullname_with_scope();
|
||||
return {};
|
||||
}
|
||||
if (base_shape->isa<abstract::Shape>()) {
|
||||
if (output_idx != 0) {
|
||||
MS_LOG(EXCEPTION) << "The node " << node->fullname_with_scope() << "is a single output node but got index ["
|
||||
<< output_idx;
|
||||
}
|
||||
auto shape_ptr = base_shape->cast<abstract::ShapePtr>();
|
||||
MS_EXCEPTION_IF_NULL(shape_ptr);
|
||||
return shape_ptr->shape();
|
||||
} else if (base_shape->isa<abstract::NoShape>()) {
|
||||
return ShapeVector();
|
||||
} else if (base_shape->isa<abstract::TupleShape>()) {
|
||||
auto tuple_shape = base_shape->cast<abstract::TupleShapePtr>();
|
||||
MS_EXCEPTION_IF_NULL(tuple_shape);
|
||||
if (output_idx >= tuple_shape->size()) {
|
||||
MS_LOG(EXCEPTION) << "Output index " << output_idx << "is larger than output number " << tuple_shape->size()
|
||||
<< node->fullname_with_scope();
|
||||
}
|
||||
auto b_shp = (*tuple_shape)[output_idx];
|
||||
if (b_shp->isa<abstract::Shape>()) {
|
||||
auto shape_ptr = b_shp->cast<abstract::ShapePtr>();
|
||||
MS_EXCEPTION_IF_NULL(shape_ptr);
|
||||
return shape_ptr->shape();
|
||||
} else if (b_shp->isa<abstract::NoShape>()) {
|
||||
return ShapeVector();
|
||||
} else if (b_shp->isa<abstract::TupleShape>()) {
|
||||
MS_LOG(INFO) << "The output shape of node:" << node->fullname_with_scope() << " index:" << output_idx
|
||||
<< " is a TupleShape:" << base_shape->ToString();
|
||||
return ShapeVector();
|
||||
} else {
|
||||
MS_LOG(EXCEPTION) << "The output type of ApplyKernel index:" << output_idx
|
||||
<< " should be a NoShape , ArrayShape or a TupleShape, but it is " << base_shape->ToString()
|
||||
<< "node :" << node->fullname_with_scope() << ".";
|
||||
}
|
||||
}
|
||||
return ShapeVector();
|
||||
}
|
||||
|
||||
int GetDataTypeFromAnfNode(const AnfNodePtr &anf_node, TypeId *type_id) {
|
||||
if (anf_node == nullptr || type_id == nullptr) {
|
||||
MS_LOG(ERROR) << "anf_node or type_id is nullptr.";
|
||||
|
@ -1255,22 +1312,44 @@ void PrintFuncGraph(const FuncGraphPtr &func_graph, const std::string &output_fi
|
|||
return;
|
||||
}
|
||||
auto nodes = func_graph->TopoSort(func_graph->get_return());
|
||||
auto type_name = [](const AnfNodePtr &anf_node) -> std::string {
|
||||
if (anf_node->cast<CNodePtr>()) {
|
||||
return GetCNodeFuncName(anf_node->cast<CNodePtr>());
|
||||
} else if (anf_node->cast<ParameterPtr>()) {
|
||||
return "Parameter";
|
||||
} else if (anf_node->cast<ValueNodePtr>()) {
|
||||
return "ValueNode";
|
||||
}
|
||||
return anf_node->ToString();
|
||||
};
|
||||
for (auto &node : nodes) {
|
||||
auto cnode = node->cast<CNodePtr>();
|
||||
if (cnode == nullptr) {
|
||||
fp << "Node " << node->fullname_with_scope() << std::endl;
|
||||
if (IsValueNode<Primitive>(node)) {
|
||||
continue;
|
||||
}
|
||||
auto cnode = node->cast<CNodePtr>();
|
||||
if (cnode == nullptr) {
|
||||
fp << node->fullname_with_scope() << ", type: " << type_name(node)
|
||||
<< ", shape: " << GetAnfNodeOutputShape(node, 0) << std::endl;
|
||||
continue;
|
||||
}
|
||||
fp << "Node " << node->fullname_with_scope() << ", type: " << GetCNodeFuncName(cnode) << std::endl;
|
||||
auto inputs = cnode->inputs();
|
||||
for (size_t i = 1; i < inputs.size(); i++) {
|
||||
auto input_as_cnode = inputs[i]->cast<CNodePtr>();
|
||||
if (input_as_cnode) {
|
||||
fp << "----input " << inputs[i]->fullname_with_scope() << ", type " << GetCNodeFuncName(input_as_cnode)
|
||||
<< std::endl;
|
||||
} else {
|
||||
fp << "---input " << inputs[i]->fullname_with_scope() << ", type " << inputs[i]->ToString() << std::endl;
|
||||
auto prim = GetValueNode<PrimitivePtr>(cnode->input(0));
|
||||
Format format = DEFAULT_FORMAT;
|
||||
if (prim && prim->HasAttr(ops::kFormat)) {
|
||||
format = static_cast<Format>(GetValue<int64_t>(prim->GetAttr(ops::kFormat)));
|
||||
}
|
||||
std::vector<int> outputs_format;
|
||||
if (prim && prim->HasAttr(kOutputsFormat)) {
|
||||
outputs_format = CastToInt(prim->GetAttr(kOutputsFormat));
|
||||
}
|
||||
fp << node->fullname_with_scope() << ", type: " << type_name(node) << ", shape: " << GetAnfNodeOutputShape(node, 0)
|
||||
<< ", format: " << format << ", output formats: " << outputs_format << std::endl;
|
||||
for (auto &input : inputs) {
|
||||
if (IsValueNode<Primitive>(input)) {
|
||||
continue;
|
||||
}
|
||||
fp << "---input " << input->fullname_with_scope() << ", type: " << type_name(input)
|
||||
<< ", shape: " << GetAnfNodeOutputShape(input, 0) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,6 +139,8 @@ bool IsTrainOp(const CNodePtr &cnode);
|
|||
|
||||
bool IsMarkedTrainOp(const CNodePtr &cnode);
|
||||
|
||||
ShapeVector GetAnfNodeOutputShape(const AnfNodePtr &node, size_t output_idx);
|
||||
|
||||
int GetDataTypeFromAnfNode(const AnfNodePtr &anf_node, TypeId *type_id);
|
||||
|
||||
size_t GetOutputSize(const AnfNodePtr &anf_node);
|
||||
|
|
|
@ -182,6 +182,11 @@ STATUS DeleteRedundantTranspose::UpdateNodeFormat(const CNodePtr &cnode) {
|
|||
auto post_prim = GetValueNode<PrimitivePtr>(post_cnode->input(0));
|
||||
MS_ASSERT(post_prim != nullptr);
|
||||
post_prim->AddAttr(ops::kFormat, MakeValue<int64_t>(forward_format));
|
||||
if (prim->HasAttr(opt::kOutputsFormat)) {
|
||||
auto org_format = CastToInt(prim->GetAttr(opt::kOutputsFormat));
|
||||
std::vector<int64_t> outputs_format(org_format.size(), forward_format);
|
||||
(void)prim->AddAttr(kOutputsFormat, MakeValue(outputs_format));
|
||||
}
|
||||
}
|
||||
return lite::RET_OK;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,11 @@ STATUS ToFormatBase::ModifyCNode(const CNodePtr &cnode) {
|
|||
auto insert_pos = sensitive_ops_[prim->name()];
|
||||
if (insert_pos.empty() || std::find(insert_pos.begin(), insert_pos.end(), 1) != insert_pos.end()) {
|
||||
prim->AddAttr(ops::kFormat, MakeValue<int64_t>(format_));
|
||||
if (prim->HasAttr(opt::kOutputsFormat)) {
|
||||
auto org_format = CastToInt(prim->GetAttr(opt::kOutputsFormat));
|
||||
std::vector<int64_t> outputs_format(org_format.size(), format_);
|
||||
(void)prim->AddAttr(kOutputsFormat, MakeValue(outputs_format));
|
||||
}
|
||||
}
|
||||
auto abstract_base = cnode->abstract();
|
||||
MS_ASSERT(abstract_base != nullptr);
|
||||
|
|
|
@ -686,10 +686,17 @@ int DecreaseTransposeAlgo::ModifyCNodeFormat(const CNodePtr &cnode, FormatTransN
|
|||
}
|
||||
auto primitive = GetValueNode<PrimitivePtr>(cnode->input(0));
|
||||
MS_CHECK_TRUE_MSG(primitive != nullptr, lite::RET_ERROR, "GetValueNode Failed");
|
||||
mindspore::Format new_format;
|
||||
if (pre_trans_type == kNHWC2NCHW) {
|
||||
primitive->AddAttr(ops::kFormat, MakeValue<int64_t>(mindspore::NCHW));
|
||||
new_format = mindspore::NCHW;
|
||||
} else {
|
||||
primitive->AddAttr(ops::kFormat, MakeValue<int64_t>(mindspore::NHWC));
|
||||
new_format = mindspore::NHWC;
|
||||
}
|
||||
primitive->AddAttr(ops::kFormat, MakeValue<int64_t>(new_format));
|
||||
if (primitive->HasAttr(opt::kOutputsFormat)) {
|
||||
auto org_format = CastToInt(primitive->GetAttr(opt::kOutputsFormat));
|
||||
std::vector<int64_t> outputs_format(org_format.size(), new_format);
|
||||
(void)primitive->AddAttr(kOutputsFormat, MakeValue(outputs_format));
|
||||
}
|
||||
return lite::RET_OK;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue