MSLite, GPU and Ascend bugfix

This commit is contained in:
xuyongfei 2022-11-07 11:16:14 +08:00
parent 550ff897c2
commit 36366ff80c
26 changed files with 556 additions and 184 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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_;

View File

@ -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();

View File

@ -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;

View File

@ -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_

View File

@ -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,

View File

@ -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_;
};

View File

@ -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";

View File

@ -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());

View File

@ -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()) {

View File

@ -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.";

View File

@ -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;
}

View File

@ -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,

View File

@ -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> &param) {
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.";

View File

@ -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;

View File

@ -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

View File

@ -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_

View File

@ -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;
}
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}