forked from mindspore-Ecosystem/mindspore
!25863 fix dynamic shape bugs
Merge pull request !25863 from fangzehua/fix_dy_1028
This commit is contained in:
commit
a3441bbfb5
|
@ -81,7 +81,7 @@ void SliceCPUKernel::InitSliceParam(const std::vector<size_t> &input_shape, cons
|
|||
slice_size = dim_len - begin_pos;
|
||||
}
|
||||
if (slice_size <= 0) {
|
||||
MS_LOG(EXCEPTION) << "Slice requires the each dimension slice size must be greater than 0.";
|
||||
MS_LOG(EXCEPTION) << "Slice requires the each dimension slice size must be greater than 0 or be equal to -1.";
|
||||
}
|
||||
slice_param_.shape_[i] = dim_len;
|
||||
slice_param_.size_[i] = slice_size;
|
||||
|
|
|
@ -32,14 +32,7 @@ constexpr size_t kSliceGradMaxInputShapeSize = 4;
|
|||
void SliceGradCPUKernel::InitKernel(const CNodePtr &kernel_node) {
|
||||
MS_EXCEPTION_IF_NULL(kernel_node);
|
||||
cnode_ptr_ = kernel_node;
|
||||
begin_.clear();
|
||||
size_.clear();
|
||||
strides_.clear();
|
||||
end_.clear();
|
||||
input_element_num_.clear();
|
||||
output_element_num_.clear();
|
||||
input_shape_.clear();
|
||||
output_shape_.clear();
|
||||
ClearVectors();
|
||||
auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(kernel_node, 0);
|
||||
if (input_shape.size() > kSliceGradMaxInputShapeSize) {
|
||||
MS_LOG(EXCEPTION) << "Input dims is " << input_shape.size() << ", but SliceGradCpuKernel only support 4d or lower.";
|
||||
|
@ -83,6 +76,17 @@ void SliceGradCPUKernel::InitKernel(const CNodePtr &kernel_node) {
|
|||
CPUKernelUtils::GetElementNumEveryDim(output_shape_, &output_element_num_);
|
||||
}
|
||||
|
||||
void SliceGradCPUKernel::ClearVectors() {
|
||||
begin_.clear();
|
||||
size_.clear();
|
||||
strides_.clear();
|
||||
end_.clear();
|
||||
input_element_num_.clear();
|
||||
output_element_num_.clear();
|
||||
input_shape_.clear();
|
||||
output_shape_.clear();
|
||||
}
|
||||
|
||||
void SliceGradCPUKernel::ExpandAllMemberDims() {
|
||||
auto output_len = output_shape_.size();
|
||||
constexpr size_t expand_dims = 4;
|
||||
|
@ -107,6 +111,8 @@ void SliceGradCPUKernel::ExpandAllMemberDims() {
|
|||
|
||||
void SliceGradCPUKernel::InitParams(const std::vector<kernel::AddressPtr> &inputs) {
|
||||
auto cnode = cnode_ptr_.lock();
|
||||
ClearVectors();
|
||||
output_shape_ = AnfAlgo::GetOutputInferShape(cnode, 0);
|
||||
std::string kernel_name = AnfAlgo::GetCNodeName(cnode);
|
||||
auto begin_shape = AnfAlgo::GetPrevNodeOutputInferShape(cnode, 2);
|
||||
auto begin_ptr = reinterpret_cast<int32_t *>(inputs[2]->addr);
|
||||
|
@ -129,7 +135,8 @@ void SliceGradCPUKernel::InitParams(const std::vector<kernel::AddressPtr> &input
|
|||
[](const int32_t &value) { return value; });
|
||||
(void)std::transform(end.begin(), end.end(), std::back_inserter(end_), [](const int32_t &value) { return value; });
|
||||
if (strides_.size() != end_.size() || strides_.size() != output_shape_.size()) {
|
||||
MS_LOG(EXCEPTION) << "stride|end|input size must be equal";
|
||||
MS_LOG(EXCEPTION) << "stride|end|input size must be equal, but got begin: " << begin_ << ", size: " << size_
|
||||
<< ", input shape: " << output_shape_;
|
||||
}
|
||||
FormatArgs(true);
|
||||
} else {
|
||||
|
|
|
@ -42,6 +42,7 @@ class SliceGradCPUKernel : public CPUKernel {
|
|||
const std::vector<kernel::AddressPtr> &outputs, size_t out_offset, size_t copy_num,
|
||||
int id) const;
|
||||
void InitParams(const std::vector<kernel::AddressPtr> &inputs);
|
||||
void ClearVectors();
|
||||
void ExpandAllMemberDims();
|
||||
bool CanCopyMemoryOnAxis(size_t dim) const;
|
||||
int SignOfStride(size_t axis) const;
|
||||
|
|
|
@ -573,7 +573,15 @@ void ConstInputToAttr(const CNodePtr &cnode, const std::unordered_set<size_t> &i
|
|||
if (i >= input_names_vec.size()) {
|
||||
MS_LOG(EXCEPTION) << "index " << i << " is larger than input names size [" << input_names_vec.size() << "]";
|
||||
}
|
||||
primitive->set_attr(input_names_vec[i], value_node->value());
|
||||
auto value = value_node->value();
|
||||
if (value->isa<tensor::Tensor>()) {
|
||||
auto tensor = value->cast<tensor::TensorPtr>();
|
||||
if (tensor->data().const_data() == nullptr) {
|
||||
need_update = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
primitive->set_attr(input_names_vec[i], value);
|
||||
need_update = true;
|
||||
} else {
|
||||
new_inputs.push_back(inputs[i + 1]);
|
||||
|
|
|
@ -683,7 +683,9 @@ EvalResultPtr PythonPrimEvaluator::EvalPrim(const AnalysisEnginePtr &, const Abs
|
|||
|
||||
const auto eval_result = evaluator_cache_mgr_->GetValue(args);
|
||||
if (eval_result != nullptr) {
|
||||
return eval_result;
|
||||
auto abs = eval_result->abstract()->Clone();
|
||||
auto attr = eval_result->attribute();
|
||||
return std::make_shared<EvalResult>(abs, attr);
|
||||
}
|
||||
|
||||
auto py_args = PreparePyInputs(prim_py_, args);
|
||||
|
|
|
@ -85,7 +85,13 @@ void KernelActor::Run(OpContext<DeviceTensor> *const context) {
|
|||
|
||||
// Infer kernel shape and update abstract info for dynamic shape kernel.
|
||||
if (is_dynamic_shape_) {
|
||||
device_contexts_[0]->UpdateDynamicShape(kernel_);
|
||||
try {
|
||||
device_contexts_[0]->UpdateDynamicShape(kernel_);
|
||||
} catch (const std::exception &e) {
|
||||
MsException::Instance().SetException();
|
||||
std::string error_info = "Update Dynamic shape exception: " + kernel_->fullname_with_scope();
|
||||
SET_OPCONTEXT_FAIL_RET_WITH_ERROR_BY_STRATEGY(strategy_, (*context), error_info);
|
||||
}
|
||||
}
|
||||
|
||||
FetchInputDeviceTensor(context);
|
||||
|
|
|
@ -94,7 +94,7 @@ AbstractBasePtr InferImplStack(const AnalysisEnginePtr &, const PrimitivePtr &pr
|
|||
// Inputs: a tuple of tensor.
|
||||
const std::string op_name = primitive->name();
|
||||
CheckArgsSize(op_name, args_spec_list, 1);
|
||||
auto arg = CheckArg<AbstractTuple>(op_name, args_spec_list, 0);
|
||||
auto arg = CheckArg<AbstractSequeue>(op_name, args_spec_list, 0);
|
||||
if (arg->elements().empty()) {
|
||||
MS_LOG(EXCEPTION) << "Arg elements is empty.";
|
||||
}
|
||||
|
@ -838,7 +838,7 @@ AbstractBasePtr InferImplReshape(const AnalysisEnginePtr &, const PrimitivePtr &
|
|||
if (it_first != shape.end()) {
|
||||
auto it_second = find(it_first + 1, shape.end(), -1);
|
||||
if (it_second != shape.end()) {
|
||||
MS_LOG(EXCEPTION) << "At most one component of input shape can be -1";
|
||||
MS_LOG(EXCEPTION) << "At most one component of input shape can be -1, but got " << shape;
|
||||
}
|
||||
auto index = LongToSize(std::distance(shape.begin(), it_first));
|
||||
int64_t infer_value = x_num;
|
||||
|
|
|
@ -98,7 +98,12 @@ std::vector<int64_t> GetDependsFormMap(const CNodePtr &cnode) {
|
|||
MS_EXCEPTION_IF_NULL(primitive);
|
||||
auto iter = dynamic_shape_depends.find(primitive->ToString());
|
||||
if (iter != dynamic_shape_depends.end()) {
|
||||
return iter->second;
|
||||
int64_t cnode_input_size = SizeToLong(cnode->inputs().size());
|
||||
std::vector<int64_t> res;
|
||||
auto ori = iter->second;
|
||||
(void)std::copy_if(ori.begin(), ori.end(), std::back_inserter(res),
|
||||
[&](auto idx) { return idx < cnode_input_size - 1; });
|
||||
return res;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -123,6 +128,7 @@ PrimitiveEvalImplMap &GetPrimitiveToEvalImplMap() {
|
|||
{prim::kPrimReal, {InferImplReal, nullptr, true}},
|
||||
// Array
|
||||
{prim::kPrimRange, {InferImplRange, nullptr, true}},
|
||||
{prim::kPrimStack, {InferImplStack, nullptr, true}},
|
||||
{prim::kPrimScalarToArray, {InferImplScalarToArray, nullptr, true}},
|
||||
{prim::kPrimArrayToScalar, {InferImplArrayToScalar, nullptr, true}},
|
||||
{prim::kPrimBroadcastShape, {InferImplBroadCastShape, nullptr, true}},
|
||||
|
@ -255,7 +261,6 @@ PrimitiveEvalImplMap &GetPrimitiveToBackendEvalImplMap() {
|
|||
{prim::kPrimLinSpace, {InferImplLinSpace, nullptr, true}},
|
||||
|
||||
{prim::kPrimLess, {InferImplLess, nullptr, true}},
|
||||
{prim::kPrimStack, {InferImplStack, nullptr, true}},
|
||||
{prim::kPrimPad, {InferImplPad, nullptr, true}},
|
||||
{prim::kPrimUnsortedSegmentSum, {InferImplUnsortedSegmentSum, nullptr, true}},
|
||||
{prim::kPrimDiv, {InferImplDiv, nullptr, true}},
|
||||
|
|
|
@ -35,6 +35,7 @@ abstract::ShapePtr SliceInferShape(const PrimitivePtr &primitive, const std::vec
|
|||
MS_EXCEPTION_IF_NULL(item);
|
||||
}
|
||||
auto shape_map = CheckAndConvertUtils::ConvertShapePtrToShapeMap(input_args[0]->BuildShape());
|
||||
auto input_shape = shape_map[kShape];
|
||||
auto min_shape = shape_map[kMinShape];
|
||||
auto max_shape = shape_map[kMaxShape];
|
||||
std::vector<std::vector<int64_t>> input_values;
|
||||
|
@ -47,13 +48,25 @@ abstract::ShapePtr SliceInferShape(const PrimitivePtr &primitive, const std::vec
|
|||
} else {
|
||||
tmp_input = CheckAndConvertUtils::CheckAttrTupleInt("slice args value", input_value, prim_name);
|
||||
}
|
||||
|
||||
(void)input_values.emplace_back(tmp_input);
|
||||
}
|
||||
if (max_shape.empty() && min_shape.empty()) {
|
||||
return std::make_shared<abstract::Shape>(input_values[1]);
|
||||
|
||||
auto begin_v = input_values[0];
|
||||
auto size_v = input_values[1];
|
||||
auto rank = input_shape.size();
|
||||
if (begin_v.size() != rank || size_v.size() != rank) {
|
||||
MS_LOG(EXCEPTION) << "For Slice, the shape of input|begin|size must be equal.";
|
||||
}
|
||||
return std::make_shared<abstract::Shape>(input_values[1], min_shape, max_shape);
|
||||
|
||||
for (size_t i = 0; i < size_v.size(); ++i) {
|
||||
if (size_v[i] == -1) {
|
||||
size_v[i] = input_shape[i] - begin_v[i];
|
||||
}
|
||||
}
|
||||
if (max_shape.empty() && min_shape.empty()) {
|
||||
return std::make_shared<abstract::Shape>(size_v);
|
||||
}
|
||||
return std::make_shared<abstract::Shape>(size_v, min_shape, max_shape);
|
||||
}
|
||||
|
||||
TypePtr SliceInferType(const PrimitivePtr &prim, const std::vector<AbstractBasePtr> &input_args) {
|
||||
|
|
|
@ -69,6 +69,12 @@ abstract::ShapePtr TileInferShape(const PrimitivePtr &primitive, const std::vect
|
|||
multiples_v = CheckAndConvertUtils::CheckAttrTupleInt("tile multiples value", multiple_value, prim_name);
|
||||
}
|
||||
|
||||
for (auto multiple : multiples_v) {
|
||||
if (multiple <= 0) {
|
||||
MS_LOG(EXCEPTION) << "multiples in Tile should be an int and must > 0, but got " << multiples_v;
|
||||
}
|
||||
}
|
||||
|
||||
auto infer_shape = GetInferShape(input_shape, multiples_v);
|
||||
if (max_shape.empty() && min_shape.empty()) {
|
||||
return std::make_shared<abstract::Shape>(infer_shape);
|
||||
|
|
|
@ -247,6 +247,7 @@ def _tile_shape(multiples, shapex):
|
|||
else:
|
||||
ret.append(1)
|
||||
ret.append(shapex[j])
|
||||
j += 1
|
||||
len_cmp += 1
|
||||
return tuple(ret)
|
||||
|
||||
|
@ -262,24 +263,33 @@ def get_bprop_tile(self):
|
|||
|
||||
def bprop(x, multiples, out, dout):
|
||||
shapex = shape_op(x)
|
||||
if isinstance(multiples, tuple):
|
||||
if -1 in shapex:
|
||||
shapex = dyn_shape_op(x)
|
||||
# if shapex or multiples not tuple, it should be dynamic shape.
|
||||
if isinstance(multiples, tuple) and isinstance(shapex, tuple):
|
||||
r_shape = _tile_shape(multiples, shapex)
|
||||
else:
|
||||
if isinstance(multiples, tuple):
|
||||
multiples = tuple_to_array(multiples)
|
||||
multiples = cast(multiples, mstype.int64)
|
||||
len_multi = size_op(multiples)
|
||||
rank = len(shapex)
|
||||
shape_tensor = cast(tuple_to_array(shapex), mstype.int64)
|
||||
if isinstance(shapex, tuple):
|
||||
shape_tensor = cast(tuple_to_array(shapex), mstype.int64)
|
||||
else:
|
||||
shape_tensor = shapex
|
||||
if len_multi > rank:
|
||||
one_tensor = ones((len_multi - rank,), mstype.int64)
|
||||
shape_tensor = concat((shape_tensor, one_tensor))
|
||||
shape_tensor = concat((one_tensor, shape_tensor))
|
||||
elif len_multi < rank:
|
||||
one_tensor = ones((rank - len_multi,), mstype.int64)
|
||||
multiples = concat((multiples, one_tensor))
|
||||
multiples = concat((one_tensor, multiples))
|
||||
tile_shape = stack_op((multiples, shape_tensor))
|
||||
r_shape = reshape(tile_shape, (-1,))
|
||||
r_shape = P.Reshape()(tile_shape, (-1,))
|
||||
|
||||
# 0 represents the start index, and 2 represents the step
|
||||
axis = F.make_range(0, len(r_shape), 2)
|
||||
dx = reduce_sum(reshape(dout, r_shape), axis)
|
||||
dx = reduce_sum(P.Reshape()(dout, r_shape), axis)
|
||||
dx = reshape(dx, shapex)
|
||||
return dx, zeros_like(multiples)
|
||||
|
||||
|
|
|
@ -7,4 +7,4 @@ j
|
|||
bprop.6:x*
|
||||
bprop.6:out*
|
||||
bprop.6:dout2
|
||||
bprop.6:[CNode]:2:@dae47635340bc244097f692e3d086cc9ae28fd823d60946e421051e28dbccdadP
|
||||
bprop.6:[CNode]:2:@8e2475d2a78429b63ff06e217cb14568f5d5fe5054a046c67278551d2456d5ccP
|
|
@ -7,4 +7,4 @@ j
|
|||
bprop.7:x*
|
||||
bprop.7:out*
|
||||
bprop.7:dout2
|
||||
bprop.7:[CNode]:2:@dae47635340bc244097f692e3d086cc9ae28fd823d60946e421051e28dbccdadP
|
||||
bprop.7:[CNode]:2:@8e2475d2a78429b63ff06e217cb14568f5d5fe5054a046c67278551d2456d5ccP
|
|
@ -5,4 +5,4 @@ d
|
|||
bprop.2:x*
|
||||
bprop.2:out*
|
||||
bprop.2:dout2
|
||||
bprop.2:[CNode]:1:@dae47635340bc244097f692e3d086cc9ae28fd823d60946e421051e28dbccdadP
|
||||
bprop.2:[CNode]:1:@8e2475d2a78429b63ff06e217cb14568f5d5fe5054a046c67278551d2456d5ccP
|
|
@ -7,4 +7,4 @@ i
|
|||
bprop.4:x*
|
||||
bprop.4:out*
|
||||
bprop.4:dout2
|
||||
bprop.4:[CNode]:2:@dae47635340bc244097f692e3d086cc9ae28fd823d60946e421051e28dbccdadP
|
||||
bprop.4:[CNode]:2:@8e2475d2a78429b63ff06e217cb14568f5d5fe5054a046c67278551d2456d5ccP
|
|
@ -7,4 +7,4 @@ i
|
|||
bprop.3:x*
|
||||
bprop.3:out*
|
||||
bprop.3:dout2
|
||||
bprop.3:[CNode]:2:@dae47635340bc244097f692e3d086cc9ae28fd823d60946e421051e28dbccdadP
|
||||
bprop.3:[CNode]:2:@8e2475d2a78429b63ff06e217cb14568f5d5fe5054a046c67278551d2456d5ccP
|
|
@ -7,4 +7,4 @@ i
|
|||
bprop.5:x*
|
||||
bprop.5:out*
|
||||
bprop.5:dout2
|
||||
bprop.5:[CNode]:2:@dae47635340bc244097f692e3d086cc9ae28fd823d60946e421051e28dbccdadP
|
||||
bprop.5:[CNode]:2:@8e2475d2a78429b63ff06e217cb14568f5d5fe5054a046c67278551d2456d5ccP
|
|
@ -2001,19 +2001,16 @@ class Tile(PrimitiveWithInfer):
|
|||
def __infer__(self, x, multiples):
|
||||
multiples_v = multiples['value']
|
||||
if multiples_v is None:
|
||||
if len(multiples['shape']) != 1:
|
||||
raise ValueError(f'For \'{self.name}\' the dim of multiples must be 1.')
|
||||
rank = max(len(x['shape']), multiples['shape'][0])
|
||||
out_shape = [-1] * rank
|
||||
if 'max_shape' not in x:
|
||||
max_shape = x['shape']
|
||||
min_shape = x['shape']
|
||||
else:
|
||||
max_shape = x['max_shape']
|
||||
min_shape = x['min_shape']
|
||||
# tile can't infer min/max shape if multiples_v is None
|
||||
return {'shape': out_shape,
|
||||
'dtype': x['dtype'],
|
||||
'value': None,
|
||||
'min_shape': min_shape,
|
||||
'max_shape': max_shape
|
||||
'min_shape': [1] * rank,
|
||||
'max_shape': [1] * rank
|
||||
}
|
||||
|
||||
x_shp = x['shape']
|
||||
|
@ -2856,7 +2853,13 @@ class Slice(PrimitiveWithInfer):
|
|||
x_shp_len = len(x_shape)
|
||||
begin_v, size_v = begin['value'], size['value']
|
||||
if begin_v is None or size_v is None:
|
||||
out_shape = [-1] * size['shape'][0]
|
||||
# if size_v is not None and begin_v is None, it should be also a dynamic output shape.
|
||||
if size_v is None:
|
||||
if size['shape'][0] < 0:
|
||||
raise ValueError(f"For '{self.name}', the size shape haven't support dynamic yet.")
|
||||
out_shape = [-1] * size['shape'][0]
|
||||
else:
|
||||
out_shape = [-1] * len(size_v)
|
||||
if 'max_shape' in x:
|
||||
max_shape = x['max_shape']
|
||||
min_shape = x['min_shape']
|
||||
|
|
|
@ -487,7 +487,9 @@ class _Reduce(PrimitiveWithInfer):
|
|||
|
||||
if np_reduce_func is not None:
|
||||
value = input_x['value'].asnumpy()
|
||||
if not axis_v:
|
||||
if isinstance(axis_v, int):
|
||||
axis_v = (axis_v,)
|
||||
elif not axis_v:
|
||||
axis_v = [i for i in range(len(input_x['shape']))]
|
||||
axis_v = tuple(axis_v)
|
||||
value = np_reduce_func(value, axis_v, keepdims=self.keep_dims)
|
||||
|
|
Loading…
Reference in New Issue