|
|
@ -205,24 +205,23 @@ AbstractBasePtr InferImplUnsortedSegmentSum(const AnalysisEnginePtr &, const Pri
|
|
|
|
const AbstractBasePtrList &args_spec_list) {
|
|
|
|
const AbstractBasePtrList &args_spec_list) {
|
|
|
|
const std::string op_name = primitive->name();
|
|
|
|
const std::string op_name = primitive->name();
|
|
|
|
CheckArgsSize(op_name, args_spec_list, 3);
|
|
|
|
CheckArgsSize(op_name, args_spec_list, 3);
|
|
|
|
// input x
|
|
|
|
|
|
|
|
auto x = CheckArg<AbstractTensor>(op_name, args_spec_list, 0);
|
|
|
|
auto x = CheckArg<AbstractTensor>(op_name, args_spec_list, 0);
|
|
|
|
MS_EXCEPTION_IF_NULL(x);
|
|
|
|
MS_EXCEPTION_IF_NULL(x);
|
|
|
|
MS_EXCEPTION_IF_NULL(x->shape());
|
|
|
|
MS_EXCEPTION_IF_NULL(x->shape());
|
|
|
|
auto x_shape = x->shape()->shape();
|
|
|
|
|
|
|
|
// segment_ids
|
|
|
|
|
|
|
|
auto segment_ids = CheckArg<AbstractTensor>(op_name, args_spec_list, 1);
|
|
|
|
auto segment_ids = CheckArg<AbstractTensor>(op_name, args_spec_list, 1);
|
|
|
|
MS_EXCEPTION_IF_NULL(segment_ids);
|
|
|
|
MS_EXCEPTION_IF_NULL(segment_ids);
|
|
|
|
MS_EXCEPTION_IF_NULL(segment_ids->shape());
|
|
|
|
MS_EXCEPTION_IF_NULL(segment_ids->shape());
|
|
|
|
auto segment_ids_shape = segment_ids->shape()->shape();
|
|
|
|
auto segment_ids_shape = segment_ids->shape()->shape();
|
|
|
|
// checks on Tensors 0 and 1 types
|
|
|
|
(void)CheckTensorDType(x, {kFloat16, kFloat32, kInt32}, "Input 0 (x) for UnsortedSegmentSum should be %s");
|
|
|
|
(void)CheckTensorDType(x, {kFloat32, kInt32}, "Input 0 (x) for SequenceMask should be %s");
|
|
|
|
(void)CheckTensorDType(segment_ids, {kInt32, kInt64}, "Input 1 (segment_ids) for UnsortedSegmentSum should be %s");
|
|
|
|
(void)CheckTensorDType(segment_ids, {kInt32, kInt64}, "Input 1 (segment_ids) for SequenceMask should be %s");
|
|
|
|
// check if dynamic shape
|
|
|
|
|
|
|
|
bool x_is_dyn = (!x->shape()->min_shape().empty() && !x->shape()->max_shape().empty());
|
|
|
|
|
|
|
|
bool ids_is_dyn = (!segment_ids->shape()->min_shape().empty() && !segment_ids->shape()->max_shape().empty());
|
|
|
|
|
|
|
|
bool op_is_dynamic = x_is_dyn && ids_is_dyn;
|
|
|
|
|
|
|
|
auto x_shape = x->shape()->shape();
|
|
|
|
ShapeVector shape;
|
|
|
|
ShapeVector shape;
|
|
|
|
ShapeVector max_shape;
|
|
|
|
int64_t num_segments_value = 0;
|
|
|
|
ShapeVector min_shape;
|
|
|
|
if (args_spec_list[2]->isa<AbstractTensor>()) { // num_segments is Tensor
|
|
|
|
int64_t num_segments_value;
|
|
|
|
|
|
|
|
if (args_spec_list[2]->isa<AbstractTensor>()) { // Num segments is Tensor
|
|
|
|
|
|
|
|
auto num_segments = args_spec_list[2]->cast<AbstractTensorPtr>();
|
|
|
|
auto num_segments = args_spec_list[2]->cast<AbstractTensorPtr>();
|
|
|
|
MS_EXCEPTION_IF_NULL(num_segments);
|
|
|
|
MS_EXCEPTION_IF_NULL(num_segments);
|
|
|
|
auto num_segments_value_ptr = num_segments->BuildValue();
|
|
|
|
auto num_segments_value_ptr = num_segments->BuildValue();
|
|
|
@ -230,26 +229,48 @@ AbstractBasePtr InferImplUnsortedSegmentSum(const AnalysisEnginePtr &, const Pri
|
|
|
|
auto num_segments_tensor = num_segments_value_ptr->cast<tensor::TensorPtr>();
|
|
|
|
auto num_segments_tensor = num_segments_value_ptr->cast<tensor::TensorPtr>();
|
|
|
|
MS_EXCEPTION_IF_NULL(num_segments_tensor);
|
|
|
|
MS_EXCEPTION_IF_NULL(num_segments_tensor);
|
|
|
|
num_segments_value = *static_cast<int64_t *>(num_segments_tensor->data_c());
|
|
|
|
num_segments_value = *static_cast<int64_t *>(num_segments_tensor->data_c());
|
|
|
|
shape.emplace_back(num_segments_value);
|
|
|
|
} else if (args_spec_list[2]->isa<AbstractScalar>()) { // num_segments is Scalar
|
|
|
|
} else if (args_spec_list[2]->isa<AbstractScalar>()) { // Num segments is Scalar
|
|
|
|
|
|
|
|
auto num_segments = CheckArg<AbstractScalar>(op_name, args_spec_list, 2);
|
|
|
|
auto num_segments = CheckArg<AbstractScalar>(op_name, args_spec_list, 2);
|
|
|
|
num_segments_value = GetValue<int64_t>(num_segments->BuildValue());
|
|
|
|
num_segments_value = GetValue<int64_t>(num_segments->BuildValue());
|
|
|
|
shape.emplace_back(num_segments_value);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
MS_LOG(EXCEPTION) << "num_segments incorrect type in UnsortedSegmentSum";
|
|
|
|
MS_LOG(EXCEPTION) << "num_segments incorrect type in UnsortedSegmentSum";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (num_segments_value <= 0) {
|
|
|
|
|
|
|
|
MS_LOG(EXCEPTION) << "num_segments must be > 0 in UnsortedSegmentSum";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
shape.emplace_back(num_segments_value);
|
|
|
|
shape.insert(shape.end(), x_shape.begin() + segment_ids_shape.size(), x_shape.end());
|
|
|
|
shape.insert(shape.end(), x_shape.begin() + segment_ids_shape.size(), x_shape.end());
|
|
|
|
// calc max shape
|
|
|
|
// dims check
|
|
|
|
if (!x->shape()->max_shape().empty()) { // copy max shape from x if present
|
|
|
|
if (!op_is_dynamic) {
|
|
|
|
std::copy(x->shape()->max_shape().begin(), x->shape()->max_shape().end(), std::back_inserter(max_shape));
|
|
|
|
for (size_t i = 0; i < segment_ids_shape.size(); i++) {
|
|
|
|
} else { // copy x shape directly if not present
|
|
|
|
if (x_shape[i] != segment_ids_shape[i]) {
|
|
|
|
std::copy(x->shape()->shape().begin(), x->shape()->shape().end(), std::back_inserter(max_shape));
|
|
|
|
MS_LOG(EXCEPTION) << "Shape values of segments_ids must match with corresponding x shape values";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// calc min shape
|
|
|
|
}
|
|
|
|
min_shape.push_back(segment_ids_shape.size());
|
|
|
|
return std::make_shared<AbstractTensor>(x->element(), std::make_shared<Shape>(shape));
|
|
|
|
std::copy(x->shape()->shape().begin() + segment_ids_shape.size(), x->shape()->shape().end(),
|
|
|
|
}
|
|
|
|
back_inserter(min_shape));
|
|
|
|
// is dynamic
|
|
|
|
// return shape, min shape, max shape
|
|
|
|
ShapeVector min_shape;
|
|
|
|
|
|
|
|
ShapeVector max_shape;
|
|
|
|
|
|
|
|
min_shape.emplace_back(num_segments_value);
|
|
|
|
|
|
|
|
max_shape.emplace_back(num_segments_value);
|
|
|
|
|
|
|
|
// only run validation if shape values are known
|
|
|
|
|
|
|
|
bool x_any_shape = std::any_of(x_shape.begin(), x_shape.end(), [](int64_t dim) { return dim == Shape::SHP_ANY; });
|
|
|
|
|
|
|
|
bool ids_any_shape =
|
|
|
|
|
|
|
|
std::any_of(segment_ids_shape.begin(), segment_ids_shape.end(), [](int64_t dim) { return dim == Shape::SHP_ANY; });
|
|
|
|
|
|
|
|
if (!x_any_shape && !ids_any_shape) {
|
|
|
|
|
|
|
|
for (size_t i = 0; i < segment_ids_shape.size(); i++) {
|
|
|
|
|
|
|
|
if (x_shape[i] != segment_ids_shape[i]) {
|
|
|
|
|
|
|
|
MS_LOG(EXCEPTION) << "Shape values of segments_ids must match with corresponding x shape values";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ShapeVector x_shape_min;
|
|
|
|
|
|
|
|
ShapeVector x_shape_max;
|
|
|
|
|
|
|
|
x_shape_min = (x_is_dyn) ? x->shape()->min_shape() : x->shape()->shape();
|
|
|
|
|
|
|
|
x_shape_max = (x_is_dyn) ? x->shape()->max_shape() : x->shape()->shape();
|
|
|
|
|
|
|
|
min_shape.insert(min_shape.end(), x_shape_min.begin() + segment_ids_shape.size(), x_shape_min.end());
|
|
|
|
|
|
|
|
max_shape.insert(max_shape.end(), x_shape_max.begin() + segment_ids_shape.size(), x_shape_max.end());
|
|
|
|
return std::make_shared<AbstractTensor>(x->element(), std::make_shared<Shape>(shape, min_shape, max_shape));
|
|
|
|
return std::make_shared<AbstractTensor>(x->element(), std::make_shared<Shape>(shape, min_shape, max_shape));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|