forked from huawei/mindspore2022
1024 lines
31 KiB
C++
1024 lines
31 KiB
C++
/**
|
|
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
|
*
|
|
* Copyright 2019 Huawei Technologies Co., Ltd
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "pipeline/static_analysis/abstract_value.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include "utils/symbolic.h"
|
|
#include "pipeline/static_analysis/static_analysis.h"
|
|
#include "pipeline/static_analysis/utils.h"
|
|
|
|
namespace mindspore {
|
|
namespace abstract {
|
|
bool AbstractBase::operator==(const AbstractBase &other) const {
|
|
if (tid() != other.tid()) {
|
|
return false;
|
|
}
|
|
if (value_ == nullptr || other.value_ == nullptr) {
|
|
MS_LOG(EXCEPTION) << "If value_ is nullptr, AbstractBase::operator== should not be called. this: "
|
|
<< this->ToString() << ", other: " << other.ToString();
|
|
}
|
|
|
|
bool value_equal = *value_ == *other.value_;
|
|
bool type_equal = *type_ == *other.type_;
|
|
bool shape_equal = *shape_ == *other.shape_;
|
|
return value_equal && type_equal && shape_equal;
|
|
}
|
|
|
|
ValuePtr AbstractBase::BuildValue() const {
|
|
if (value_ == nullptr) {
|
|
return RealBuildValue();
|
|
}
|
|
return value_;
|
|
}
|
|
|
|
AbstractBasePtr AbstractBase::Broaden() const {
|
|
AbstractBasePtr clone = Clone();
|
|
clone->set_value(kAnyValue);
|
|
clone->set_sparse_grad(sparse_grad_);
|
|
return clone;
|
|
}
|
|
|
|
std::string AbstractBase::ToString() const {
|
|
std::ostringstream buffer;
|
|
std::string value = std::string("value is null");
|
|
if (value_ != nullptr) {
|
|
value = value_->ToString();
|
|
}
|
|
MS_EXCEPTION_IF_NULL(type_);
|
|
MS_EXCEPTION_IF_NULL(shape_);
|
|
buffer << type_name() << "("
|
|
<< "Type: " << type_->ToString() << " Value: " << value << " Shape: " << shape_->ToString()
|
|
<< " sparse_grad: " << sparse_grad_ << ")";
|
|
return buffer.str();
|
|
}
|
|
|
|
AbstractBasePtr AbstractScalar::Broaden() const { return AbstractBase::Broaden(); }
|
|
|
|
AbstractBasePtr AbstractScalar::Join(const AbstractBasePtr &other) {
|
|
MS_EXCEPTION_IF_NULL(other);
|
|
if (*this == *other) {
|
|
auto ret = shared_from_base<AbstractBase>();
|
|
ret->set_sparse_grad(sparse_grad());
|
|
return ret;
|
|
}
|
|
auto value_self = GetValueTrack();
|
|
MS_EXCEPTION_IF_NULL(value_self);
|
|
ValuePtr res_value = ValueJoin(value_self, other->GetValueTrack());
|
|
TypePtr res_type = TypeJoin(GetTypeTrack(), other->GetTypeTrack());
|
|
if (res_value == value_self) {
|
|
auto ret = shared_from_base<AbstractBase>();
|
|
ret->set_sparse_grad(sparse_grad());
|
|
return ret;
|
|
}
|
|
auto ret = std::make_shared<AbstractScalar>(res_value, res_type);
|
|
ret->set_sparse_grad(sparse_grad());
|
|
return ret;
|
|
}
|
|
|
|
AbstractBasePtr AbstractType::Clone() const {
|
|
ValuePtr value_self = GetValueTrack();
|
|
if (value_self == nullptr || !value_self->isa<Type>()) {
|
|
return nullptr;
|
|
}
|
|
TypePtr type_self = value_self->cast<TypePtr>();
|
|
return std::make_shared<AbstractType>(type_self->Clone());
|
|
}
|
|
|
|
bool AbstractType::operator==(const AbstractBase &other) const {
|
|
if (tid() != other.tid()) {
|
|
return false;
|
|
}
|
|
// Have to compare TypePtr with value;
|
|
ValuePtr value_self = GetValueTrack();
|
|
ValuePtr value_other = other.GetValueTrack();
|
|
if (value_self == nullptr || value_other == nullptr) {
|
|
MS_LOG(EXCEPTION) << "AbstractType value should not be nullptr. this: " << this->ToString()
|
|
<< ", other: " << other.ToString();
|
|
}
|
|
if (!value_self->isa<Type>() || !value_other->isa<Type>()) {
|
|
return false;
|
|
}
|
|
TypePtr type_self = value_self->cast<TypePtr>();
|
|
TypePtr type_other = value_other->cast<TypePtr>();
|
|
bool value_equal = *type_self == *type_other;
|
|
return value_equal;
|
|
}
|
|
|
|
std::string AbstractType::ToString() const {
|
|
std::ostringstream buffer;
|
|
ValuePtr value_self = GetValueTrack();
|
|
if (value_self == nullptr) {
|
|
buffer << "AbstractType value: nullptr";
|
|
return buffer.str();
|
|
}
|
|
if (!value_self->isa<Type>()) {
|
|
buffer << type_name() << "(Value: nullptr)";
|
|
return buffer.str();
|
|
}
|
|
TypePtr type_self = value_self->cast<TypePtr>();
|
|
MS_EXCEPTION_IF_NULL(type_self);
|
|
buffer << type_name() << "("
|
|
<< "Value: " << type_self->ToString() << ")";
|
|
return buffer.str();
|
|
}
|
|
|
|
std::string AbstractError::ToString() const {
|
|
std::ostringstream buffer;
|
|
auto value_track = GetValueTrack();
|
|
MS_EXCEPTION_IF_NULL(value_track);
|
|
buffer << type_name() << "("
|
|
<< "Value: " << value_track->ToString() << ", Node: " << node_->DebugString() << ")";
|
|
return buffer.str();
|
|
}
|
|
|
|
AbstractBasePtr AbstractFunction::Join(const AbstractBasePtr &other) {
|
|
MS_EXCEPTION_IF_NULL(other);
|
|
auto other_func = dyn_cast<AbstractFunction>(other);
|
|
if (other_func == nullptr) {
|
|
MS_LOG(EXCEPTION) << "Join failed as type mismatch, this: " << ToString() << ", other: " << other->ToString();
|
|
}
|
|
return Join(other_func);
|
|
}
|
|
|
|
bool AbstractFunction::operator==(const AbstractBase &other) const {
|
|
if (!other.isa<AbstractFunction>()) {
|
|
return false;
|
|
}
|
|
const auto &other_func = static_cast<const AbstractFunction &>(other);
|
|
bool value_equal = (*this == other_func);
|
|
return value_equal;
|
|
}
|
|
|
|
const AbstractBasePtr AbstractSequeue::operator[](const std::size_t &dim) const {
|
|
if (dim >= size()) {
|
|
MS_LOG(EXCEPTION) << "Index [" << dim << "] Out of the size [" << size() << "] of the list.";
|
|
}
|
|
return elements_[dim];
|
|
}
|
|
|
|
std::string AbstractSequeue::ToString() const {
|
|
std::ostringstream buffer;
|
|
int i = 0;
|
|
for (const auto &ele : elements_) {
|
|
MS_EXCEPTION_IF_NULL(ele);
|
|
buffer << "element[" << i << "]: " << ele->ToString() << ",";
|
|
i++;
|
|
}
|
|
return buffer.str();
|
|
}
|
|
|
|
TypePtrList AbstractSequeue::ElementsType() const {
|
|
TypePtrList element_type_list;
|
|
for (const auto &ele : elements_) {
|
|
MS_EXCEPTION_IF_NULL(ele);
|
|
TypePtr element_type = ele->BuildType();
|
|
element_type_list.push_back(element_type);
|
|
}
|
|
return element_type_list;
|
|
}
|
|
|
|
BaseShapePtrList AbstractSequeue::ElementsShape() const {
|
|
BaseShapePtrList element_shape_list;
|
|
for (const auto &ele : elements_) {
|
|
MS_EXCEPTION_IF_NULL(ele);
|
|
BaseShapePtr element_shape = ele->BuildShape();
|
|
element_shape_list.push_back(element_shape);
|
|
}
|
|
return element_shape_list;
|
|
}
|
|
|
|
AbstractBasePtrList AbstractSequeue::ElementsClone() const {
|
|
AbstractBasePtrList ele_list;
|
|
for (const auto &ele : elements_) {
|
|
MS_EXCEPTION_IF_NULL(ele);
|
|
AbstractBasePtr clone = ele->Clone();
|
|
ele_list.push_back(clone);
|
|
}
|
|
return ele_list;
|
|
}
|
|
|
|
AbstractBasePtrList AbstractSequeue::ElementsBroaden() const {
|
|
AbstractBasePtrList ele_list;
|
|
for (const auto &ele : elements_) {
|
|
MS_EXCEPTION_IF_NULL(ele);
|
|
AbstractBasePtr broadend = ele->Broaden();
|
|
ele_list.push_back(broadend);
|
|
}
|
|
return ele_list;
|
|
}
|
|
|
|
template <typename T>
|
|
ValuePtr AbstractSequeue::ElementsBuildValue() const {
|
|
std::vector<ValuePtr> element_value_list;
|
|
for (const auto &ele : elements_) {
|
|
ValuePtr element_value = ele->BuildValue();
|
|
if (element_value->isa<AnyValue>()) {
|
|
return kAnyValue;
|
|
}
|
|
element_value_list.push_back(element_value);
|
|
}
|
|
return std::make_shared<T>(element_value_list);
|
|
}
|
|
template ValuePtr AbstractSequeue::ElementsBuildValue<ValueTuple>() const;
|
|
template ValuePtr AbstractSequeue::ElementsBuildValue<ValueList>() const;
|
|
|
|
template <typename T>
|
|
AbstractBasePtr AbstractSequeue::ElementsJoin(const AbstractBasePtr &other) {
|
|
auto other_sequeue = dyn_cast<T>(other);
|
|
if (other_sequeue == nullptr) {
|
|
MS_LOG(EXCEPTION) << "Join failed as type mismatch, this: " << ToString() << ", other: " << other->ToString();
|
|
}
|
|
auto joined_list = AbstractJoin(elements_, other_sequeue->elements_);
|
|
bool changes = false;
|
|
for (std::size_t i = 0; i < elements_.size(); i++) {
|
|
if (elements_[i] != joined_list[i]) {
|
|
changes = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!changes) {
|
|
return shared_from_base<AbstractBase>();
|
|
}
|
|
return std::make_shared<T>(joined_list);
|
|
}
|
|
template AbstractBasePtr AbstractSequeue::ElementsJoin<AbstractList>(const AbstractBasePtr &);
|
|
template AbstractBasePtr AbstractSequeue::ElementsJoin<AbstractTuple>(const AbstractBasePtr &);
|
|
|
|
std::size_t AbstractSequeue::hash() const {
|
|
std::size_t hash_sum = hash_combine(tid(), std::hash<size_t>{}(elements_.size()));
|
|
// Hashing all elements is costly, so only take at most 4 elements into account based on
|
|
// some experiments.
|
|
for (size_t i = 0; (i < elements_.size()) && (i < 4); i++) {
|
|
hash_sum = hash_combine(hash_sum, elements_[i]->hash());
|
|
}
|
|
return hash_sum;
|
|
}
|
|
|
|
bool AbstractTuple::operator==(const AbstractTuple &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
|
|
if (elements_.size() != other.elements_.size()) {
|
|
return false;
|
|
}
|
|
for (size_t i = 0; i < elements_.size(); i++) {
|
|
if (!(*(elements_[i]) == *(other.elements_[i]))) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AbstractTuple::operator==(const AbstractBase &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
|
|
if (other.isa<AbstractTuple>()) {
|
|
auto other_tuple = static_cast<const AbstractTuple *>(&other);
|
|
return *this == *other_tuple;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool AbstractList::operator==(const AbstractList &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
|
|
if (elements_.size() != other.elements_.size()) {
|
|
return false;
|
|
}
|
|
for (size_t i = 0; i < elements_.size(); i++) {
|
|
if (!(*(elements_[i]) == *(other.elements_[i]))) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AbstractList::operator==(const AbstractBase &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
|
|
if (other.isa<AbstractList>()) {
|
|
auto other_list = static_cast<const AbstractList *>(&other);
|
|
return *this == *other_list;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
TypePtr AbstractSlice::BuildType() const {
|
|
MS_EXCEPTION_IF_NULL(start_);
|
|
MS_EXCEPTION_IF_NULL(stop_);
|
|
MS_EXCEPTION_IF_NULL(step_);
|
|
TypePtr start = start_->BuildType();
|
|
TypePtr stop = stop_->BuildType();
|
|
TypePtr step = step_->BuildType();
|
|
return std::make_shared<Slice>(start, stop, step);
|
|
}
|
|
|
|
bool AbstractSlice::operator==(const AbstractSlice &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
return (*start_ == *other.start_ && *stop_ == *other.stop_ && *step_ == *other.step_);
|
|
}
|
|
|
|
bool AbstractSlice::operator==(const AbstractBase &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
if (!other.isa<AbstractSlice>()) {
|
|
return false;
|
|
}
|
|
auto other_slice = static_cast<const AbstractSlice *>(&other);
|
|
return *this == *other_slice;
|
|
}
|
|
|
|
AbstractBasePtr AbstractSlice::Clone() const {
|
|
MS_EXCEPTION_IF_NULL(start_);
|
|
MS_EXCEPTION_IF_NULL(stop_);
|
|
MS_EXCEPTION_IF_NULL(step_);
|
|
AbstractBasePtr start = start_->Clone();
|
|
AbstractBasePtr stop = stop_->Clone();
|
|
AbstractBasePtr step = step_->Clone();
|
|
return std::make_shared<AbstractSlice>(start, stop, step);
|
|
}
|
|
|
|
AbstractBasePtr AbstractSlice::Broaden() const {
|
|
MS_EXCEPTION_IF_NULL(start_);
|
|
MS_EXCEPTION_IF_NULL(stop_);
|
|
MS_EXCEPTION_IF_NULL(step_);
|
|
AbstractBasePtr start = start_->Broaden();
|
|
AbstractBasePtr stop = stop_->Broaden();
|
|
AbstractBasePtr step = step_->Broaden();
|
|
return std::make_shared<AbstractSlice>(start, stop, step);
|
|
}
|
|
|
|
std::string AbstractSlice::ToString() const {
|
|
std::ostringstream buffer;
|
|
buffer << type_name() << "[";
|
|
MS_EXCEPTION_IF_NULL(start_);
|
|
buffer << start_->ToString() << " : ";
|
|
MS_EXCEPTION_IF_NULL(stop_);
|
|
buffer << stop_->ToString() << " : ";
|
|
MS_EXCEPTION_IF_NULL(step_);
|
|
buffer << step_->ToString();
|
|
buffer << "]";
|
|
return buffer.str();
|
|
}
|
|
|
|
ValuePtr AbstractSlice::RealBuildValue() const {
|
|
MS_EXCEPTION_IF_NULL(start_);
|
|
MS_EXCEPTION_IF_NULL(stop_);
|
|
MS_EXCEPTION_IF_NULL(step_);
|
|
ValuePtr start = start_->BuildValue();
|
|
ValuePtr stop = stop_->BuildValue();
|
|
ValuePtr step = step_->BuildValue();
|
|
if (start->isa<AnyValue>() || stop->isa<AnyValue>() || step->isa<AnyValue>()) {
|
|
return kAnyValue;
|
|
}
|
|
return std::make_shared<ValueSlice>(start, stop, step);
|
|
}
|
|
|
|
std::size_t AbstractSlice::hash() const {
|
|
MS_EXCEPTION_IF_NULL(start_);
|
|
MS_EXCEPTION_IF_NULL(stop_);
|
|
MS_EXCEPTION_IF_NULL(step_);
|
|
return hash_combine({tid(), start_->hash(), stop_->hash(), step_->hash()});
|
|
}
|
|
|
|
TypePtr AbstractTensor::BuildType() const {
|
|
MS_EXCEPTION_IF_NULL(element_);
|
|
TypePtr element_type = element_->BuildType();
|
|
return std::make_shared<TensorType>(element_type);
|
|
}
|
|
|
|
BaseShapePtr AbstractTensor::BuildShape() const {
|
|
auto shape = GetShapeTrack();
|
|
// Guard from using set_shape(nullptr)
|
|
if (shape == nullptr) {
|
|
return kNoShape;
|
|
}
|
|
return shape;
|
|
}
|
|
|
|
AbstractBasePtr AbstractTensor::Join(const AbstractBasePtr &other) {
|
|
auto other_tensor = dyn_cast<AbstractTensor>(other);
|
|
if (other_tensor == nullptr) {
|
|
MS_LOG(EXCEPTION) << "Join failed as type mismatch, this: " << ToString() << ", other: " << other->ToString();
|
|
}
|
|
auto element = element_->Join(other_tensor->element_);
|
|
auto shape = ShapeJoin(this->shape(), other_tensor->shape());
|
|
auto ret = std::make_shared<AbstractTensor>(element, shape);
|
|
ret->set_sparse_grad(sparse_grad());
|
|
return ret;
|
|
}
|
|
|
|
bool AbstractTensor::operator==(const AbstractTensor &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
|
|
auto v1 = GetValueTrack();
|
|
auto v2 = other.GetValueTrack();
|
|
if (v1 == nullptr || v2 == nullptr) {
|
|
MS_LOG(EXCEPTION) << "The value of AbstractTensor is nullptr";
|
|
}
|
|
|
|
bool is_value_equal = (v1 == v2);
|
|
if (v1->isa<AnyValue>() && v2->isa<AnyValue>()) {
|
|
is_value_equal = true;
|
|
}
|
|
return (*element_ == *other.element_) && (*shape() == *other.shape()) && is_value_equal;
|
|
}
|
|
|
|
bool AbstractTensor::operator==(const AbstractBase &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
|
|
if (other.isa<AbstractTensor>()) {
|
|
auto other_tensor = static_cast<const AbstractTensor *>(&other);
|
|
return *this == *other_tensor;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
AbstractBasePtr AbstractTensor::Clone() const {
|
|
MS_EXCEPTION_IF_NULL(element_);
|
|
auto clone = std::make_shared<AbstractTensor>(element_->Clone());
|
|
ShapePtr shp = shape();
|
|
clone->set_shape(shp->Clone());
|
|
clone->set_value(GetValueTrack());
|
|
clone->set_sparse_grad(sparse_grad());
|
|
return clone;
|
|
}
|
|
|
|
AbstractBasePtr AbstractTensor::Broaden() const {
|
|
MS_EXCEPTION_IF_NULL(element_);
|
|
auto broaden = std::make_shared<AbstractTensor>(element_->Broaden());
|
|
auto shp = shape();
|
|
broaden->set_shape(shp->Clone());
|
|
broaden->set_value(kAnyValue);
|
|
broaden->set_sparse_grad(sparse_grad());
|
|
return broaden;
|
|
}
|
|
|
|
AbstractBasePtr AbstractTensor::BroadenWithShape() const {
|
|
MS_EXCEPTION_IF_NULL(element_);
|
|
auto broaden = std::make_shared<AbstractTensor>(element_->Broaden());
|
|
auto shp = shape()->Clone();
|
|
shp->Broaden();
|
|
broaden->set_shape(shp);
|
|
broaden->set_value(kAnyValue);
|
|
broaden->set_sparse_grad(sparse_grad());
|
|
return broaden;
|
|
}
|
|
|
|
ShapePtr AbstractTensor::shape() const {
|
|
auto shp = dyn_cast<Shape>(GetShapeTrack());
|
|
if (shp == nullptr) {
|
|
MS_LOG(EXCEPTION) << "Tensor should have a shape.";
|
|
}
|
|
return shp;
|
|
}
|
|
|
|
std::string AbstractTensor::ToString() const {
|
|
std::ostringstream buffer;
|
|
BaseShapePtr shape_track = GetShapeTrack();
|
|
MS_EXCEPTION_IF_NULL(shape_track);
|
|
MS_EXCEPTION_IF_NULL(element_);
|
|
auto value_track = GetValueTrack();
|
|
MS_EXCEPTION_IF_NULL(value_track);
|
|
buffer << type_name() << "("
|
|
<< "shape: " << shape_track->ToString() << ", element: " << element_->ToString()
|
|
<< ", value_ptr: " << value_track << ", value: " << value_track->ToString() << " sparse_grad " << sparse_grad()
|
|
<< ")";
|
|
return buffer.str();
|
|
}
|
|
|
|
TypePtr AbstractDictionary::BuildType() const {
|
|
std::vector<std::pair<std::string, TypePtr>> key_values;
|
|
for (const auto &item : key_values_) {
|
|
MS_EXCEPTION_IF_NULL(item.second);
|
|
TypePtr type = item.second->BuildType();
|
|
key_values.emplace_back(item.first, type);
|
|
}
|
|
return std::make_shared<Dictionary>(key_values);
|
|
}
|
|
|
|
bool AbstractDictionary::operator==(const AbstractDictionary &other) const {
|
|
if (key_values_.size() != other.key_values_.size()) {
|
|
return false;
|
|
}
|
|
|
|
for (size_t index = 0; index < key_values_.size(); index++) {
|
|
if (key_values_[index].first != other.key_values_[index].first) {
|
|
return false;
|
|
}
|
|
if (!(*key_values_[index].second == *other.key_values_[index].second)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AbstractDictionary::operator==(const AbstractBase &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
if (other.isa<AbstractDictionary>()) {
|
|
auto other_class = static_cast<const AbstractDictionary *>(&other);
|
|
return *this == *other_class;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
AbstractBasePtr AbstractDictionary::Clone() const {
|
|
std::vector<AbstractAttribute> kv;
|
|
(void)std::transform(key_values_.begin(), key_values_.end(), std::back_inserter(kv),
|
|
[](const AbstractAttribute &item) {
|
|
MS_EXCEPTION_IF_NULL(item.second);
|
|
return std::make_pair(item.first, item.second->Clone());
|
|
});
|
|
return std::make_shared<AbstractDictionary>(kv);
|
|
}
|
|
|
|
AbstractBasePtr AbstractDictionary::Broaden() const {
|
|
std::vector<AbstractAttribute> kv;
|
|
(void)std::transform(key_values_.begin(), key_values_.end(), std::back_inserter(kv),
|
|
[](const AbstractAttribute &item) {
|
|
MS_EXCEPTION_IF_NULL(item.second);
|
|
return std::make_pair(item.first, item.second->Broaden());
|
|
});
|
|
return std::make_shared<AbstractDictionary>(kv);
|
|
}
|
|
|
|
std::string AbstractDictionary::ToString() const {
|
|
std::ostringstream buffer;
|
|
buffer << type_name() << "{ ";
|
|
for (const auto &kv : key_values_) {
|
|
MS_EXCEPTION_IF_NULL(kv.second);
|
|
buffer << "(" << kv.first << ": " << kv.second->ToString() << ") ";
|
|
}
|
|
buffer << "}";
|
|
return buffer.str();
|
|
}
|
|
|
|
std::size_t AbstractDictionary::hash() const {
|
|
std::size_t hash_sum = std::accumulate(key_values_.begin(), key_values_.end(), tid(),
|
|
[](std::size_t hash_sum, const AbstractAttribute &item) {
|
|
hash_sum = hash_combine(hash_sum, std::hash<std::string>()(item.first));
|
|
MS_EXCEPTION_IF_NULL(item.second);
|
|
hash_sum = hash_combine(hash_sum, item.second->hash());
|
|
return hash_sum;
|
|
});
|
|
return hash_sum;
|
|
}
|
|
|
|
ValuePtr AbstractDictionary::RealBuildValue() const {
|
|
std::vector<std::pair<std::string, ValuePtr>> key_values;
|
|
for (const auto &item : key_values_) {
|
|
MS_EXCEPTION_IF_NULL(item.second);
|
|
auto element_value = item.second->BuildValue();
|
|
MS_EXCEPTION_IF_NULL(element_value);
|
|
if (element_value->isa<AnyValue>()) {
|
|
return kAnyValue;
|
|
}
|
|
key_values.emplace_back(item.first, element_value);
|
|
}
|
|
return std::make_shared<ValueDictionary>(key_values);
|
|
}
|
|
|
|
TypePtr AbstractClass::BuildType() const {
|
|
ClassAttrVector attributes_type;
|
|
for (auto attr : attributes_) {
|
|
MS_EXCEPTION_IF_NULL(attr.second);
|
|
TypePtr type = attr.second->BuildType();
|
|
std::pair<std::string, TypePtr> elem(attr.first, type);
|
|
attributes_type.push_back(elem);
|
|
}
|
|
|
|
return std::make_shared<Class>(tag_, attributes_type, methods_);
|
|
}
|
|
|
|
bool AbstractClass::operator==(const AbstractClass &other) const {
|
|
if (!(tag_ == other.tag_)) {
|
|
return false;
|
|
}
|
|
if (attributes_.size() != other.attributes_.size()) {
|
|
return false;
|
|
}
|
|
for (size_t i = 0; i < attributes_.size(); i++) {
|
|
MS_EXCEPTION_IF_NULL(attributes_[i].second);
|
|
MS_EXCEPTION_IF_NULL(other.attributes_[i].second);
|
|
if (!(*attributes_[i].second == *other.attributes_[i].second)) {
|
|
MS_LOG(DEBUG) << "attr " << attributes_[i].first << " not equal, arg1:" << attributes_[i].second->ToString()
|
|
<< " arg2:" << other.attributes_[i].second->ToString();
|
|
return false;
|
|
}
|
|
}
|
|
// method compare;
|
|
if (methods_.size() != other.methods_.size()) {
|
|
return false;
|
|
}
|
|
for (const auto &iter : methods_) {
|
|
auto iter_other = other.methods_.find(iter.first);
|
|
if (iter_other == other.methods_.end()) {
|
|
return false;
|
|
}
|
|
if (!(*iter.second == *iter_other->second)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AbstractClass::operator==(const AbstractBase &other) const {
|
|
if (other.isa<AbstractClass>()) {
|
|
auto other_class = static_cast<const AbstractClass *>(&other);
|
|
return *this == *other_class;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
AbstractBasePtr AbstractClass::GetAttribute(const std::string &name) {
|
|
auto it = std::find_if(attributes_.begin(), attributes_.end(),
|
|
[name](const AbstractAttribute &pair) -> bool { return pair.first == name; });
|
|
if (it != attributes_.end()) {
|
|
return it->second;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
ValuePtr AbstractClass::GetMethod(const std::string &name) {
|
|
auto method_pair = methods_.find(name);
|
|
if (method_pair != methods_.end()) {
|
|
return method_pair->second;
|
|
}
|
|
return kAnyValue;
|
|
}
|
|
|
|
AbstractBasePtr AbstractClass::Clone() const {
|
|
std::vector<AbstractAttribute> attributes_clone;
|
|
for (auto attr : attributes_) {
|
|
MS_EXCEPTION_IF_NULL(attr.second);
|
|
AbstractBasePtr clone = attr.second->Clone();
|
|
AbstractAttribute elem(attr.first, clone);
|
|
attributes_clone.push_back(elem);
|
|
}
|
|
return std::make_shared<AbstractClass>(tag_, attributes_clone, methods_);
|
|
}
|
|
|
|
AbstractBasePtr AbstractClass::Broaden() const {
|
|
std::vector<AbstractAttribute> attributes_clone;
|
|
for (auto attr : attributes_) {
|
|
MS_EXCEPTION_IF_NULL(attr.second);
|
|
AbstractBasePtr clone = attr.second->Broaden();
|
|
AbstractAttribute elem(attr.first, clone);
|
|
attributes_clone.push_back(elem);
|
|
}
|
|
return std::make_shared<AbstractClass>(tag_, attributes_clone, methods_);
|
|
}
|
|
|
|
std::string AbstractClass::ToString() const {
|
|
std::ostringstream buffer;
|
|
buffer << type_name() << "(tag: " << tag_ << ") attrs:(";
|
|
bool append_comma = false;
|
|
for (const auto &attr : attributes_) {
|
|
if (append_comma) {
|
|
buffer << ", ";
|
|
} else {
|
|
append_comma = true;
|
|
}
|
|
MS_EXCEPTION_IF_NULL(attr.second);
|
|
buffer << attr.first << ":" << attr.second->ToString();
|
|
}
|
|
buffer << ") method:(";
|
|
append_comma = false;
|
|
for (const auto &iter : methods_) {
|
|
if (append_comma) {
|
|
buffer << ", ";
|
|
} else {
|
|
append_comma = true;
|
|
}
|
|
MS_EXCEPTION_IF_NULL(iter.second);
|
|
buffer << iter.first << ":" << iter.second->ToString();
|
|
}
|
|
buffer << ")";
|
|
return buffer.str();
|
|
}
|
|
|
|
std::size_t AbstractClass::hash() const {
|
|
std::size_t hash_sum = std::accumulate(attributes_.begin(), attributes_.end(), hash_combine(tid(), tag_.hash()),
|
|
[](std::size_t hash_sum, const AbstractAttribute &item) {
|
|
MS_EXCEPTION_IF_NULL(item.second);
|
|
return hash_combine(hash_sum, item.second->hash());
|
|
});
|
|
|
|
return hash_sum;
|
|
}
|
|
|
|
ValuePtr AbstractClass::RealBuildValue() const {
|
|
auto cls = BuildType()->cast<ClassPtr>();
|
|
std::unordered_map<std::string, ValuePtr> attributes_value_map;
|
|
for (const auto &attr : attributes_) {
|
|
MS_EXCEPTION_IF_NULL(attr.second);
|
|
ValuePtr _value = attr.second->BuildValue();
|
|
if (_value->isa<AnyValue>()) {
|
|
return kAnyValue;
|
|
}
|
|
attributes_value_map[attr.first] = _value;
|
|
}
|
|
cls->set_value(attributes_value_map);
|
|
return cls;
|
|
}
|
|
|
|
TypePtr AbstractJTagged::BuildType() const {
|
|
MS_EXCEPTION_IF_NULL(element_);
|
|
TypePtr subtype = element_->BuildType();
|
|
return std::make_shared<JTagged>(subtype);
|
|
}
|
|
|
|
AbstractBasePtr AbstractJTagged::Join(const AbstractBasePtr &other) {
|
|
auto other_jtagged = dyn_cast<AbstractJTagged>(other);
|
|
if (other_jtagged == nullptr) {
|
|
MS_LOG(EXCEPTION) << "Join failed as type mismatch, this: " << ToString() << ", other: " << other->ToString();
|
|
}
|
|
auto joined_elem = element_->Join(other_jtagged->element_);
|
|
return std::make_shared<AbstractJTagged>(joined_elem);
|
|
}
|
|
|
|
bool AbstractJTagged::operator==(const AbstractJTagged &other) const {
|
|
MS_EXCEPTION_IF_NULL(element_);
|
|
MS_EXCEPTION_IF_NULL(other.element_);
|
|
return (*element_ == *other.element_);
|
|
}
|
|
|
|
bool AbstractJTagged::operator==(const AbstractBase &other) const {
|
|
if (other.isa<AbstractJTagged>()) {
|
|
auto other_jtagged = static_cast<const AbstractJTagged *>(&other);
|
|
return *this == *other_jtagged;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
std::string AbstractJTagged::ToString() const {
|
|
std::ostringstream buffer;
|
|
MS_EXCEPTION_IF_NULL(element_);
|
|
buffer << type_name() << "("
|
|
<< "element: " << element_->ToString() << ")";
|
|
return buffer.str();
|
|
}
|
|
|
|
TypePtr AbstractRef::BuildType() const {
|
|
TypePtr subtype = ref_->BuildType();
|
|
TypePtr subtype_origin = ref_origin_->BuildType();
|
|
return std::make_shared<RefType>(subtype, subtype_origin);
|
|
}
|
|
|
|
bool AbstractRef::operator==(const AbstractRef &other) const {
|
|
return (*ref_ == *other.ref_) && (*ref_key_ == *other.ref_key_) && (*ref_origin_ == *other.ref_origin_);
|
|
}
|
|
|
|
bool AbstractRef::operator==(const AbstractBase &other) const {
|
|
if (other.isa<AbstractRef>()) {
|
|
auto other_conf = static_cast<const AbstractRef *>(&other);
|
|
return *this == *other_conf;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
std::string AbstractRef::ToString() const {
|
|
std::ostringstream buffer;
|
|
buffer << type_name() << "("
|
|
<< "key: " << ref_key_->ToString() << " ref_value: " << ref_->ToString()
|
|
<< " origin_value: " << ref_origin_->ToString();
|
|
auto value = GetValueTrack();
|
|
if (value) {
|
|
buffer << ", value: " << value->ToString();
|
|
}
|
|
buffer << ")";
|
|
return buffer.str();
|
|
}
|
|
|
|
bool AbstractNone::operator==(const AbstractNone &) const { return true; }
|
|
|
|
bool AbstractNone::operator==(const AbstractBase &other) const {
|
|
if (other.isa<AbstractNone>()) {
|
|
auto other_none = static_cast<const AbstractNone *>(&other);
|
|
return *this == *other_none;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
std::string AbstractNone::ToString() const {
|
|
std::ostringstream buffer;
|
|
buffer << type_name() << "(Value: None)";
|
|
return buffer.str();
|
|
}
|
|
|
|
ValuePtr AbstractNone::RealBuildValue() const { return kNone; }
|
|
|
|
bool AbstractRefKey::operator==(const AbstractRefKey &other) const {
|
|
ValuePtr value_self = GetValueTrack();
|
|
ValuePtr value_other = other.GetValueTrack();
|
|
if (value_self != nullptr && value_other != nullptr) {
|
|
if (value_self->isa<AnyValue>() && value_other->isa<AnyValue>()) {
|
|
return true;
|
|
}
|
|
if (!value_self->isa<RefKey>() || !value_other->isa<RefKey>()) {
|
|
return false;
|
|
}
|
|
RefKeyPtr type_self = value_self->cast<RefKeyPtr>();
|
|
RefKeyPtr type_other = value_other->cast<RefKeyPtr>();
|
|
return *type_self == *type_other;
|
|
} else if (value_self != nullptr || value_other != nullptr) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AbstractRefKey::operator==(const AbstractBase &other) const {
|
|
if (other.isa<AbstractRefKey>()) {
|
|
auto other_confkey = static_cast<const AbstractRefKey *>(&other);
|
|
return *this == *other_confkey;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
std::string AbstractRefKey::ToString() const {
|
|
std::ostringstream buffer;
|
|
buffer << type_name();
|
|
auto value = GetValueTrack();
|
|
if (value) {
|
|
buffer << "(value: " << value->ToString() << ")";
|
|
}
|
|
return buffer.str();
|
|
}
|
|
|
|
bool AbstractNull::operator==(const AbstractNull &) const { return true; }
|
|
|
|
bool AbstractNull::operator==(const AbstractBase &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
if (other.isa<AbstractNull>()) {
|
|
auto other_none = static_cast<const AbstractNull *>(&other);
|
|
return *this == *other_none;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
std::string AbstractNull::ToString() const {
|
|
std::ostringstream buffer;
|
|
buffer << type_name() << "(Value: Null)";
|
|
return buffer.str();
|
|
}
|
|
|
|
bool AbstractEllipsis::operator==(const AbstractEllipsis &) const { return true; }
|
|
|
|
bool AbstractEllipsis::operator==(const AbstractBase &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
if (other.isa<AbstractEllipsis>()) {
|
|
auto other_none = static_cast<const AbstractEllipsis *>(&other);
|
|
return *this == *other_none;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
std::string AbstractEllipsis::ToString() const {
|
|
std::ostringstream buffer;
|
|
buffer << type_name() << "(Value: Ellipsis)";
|
|
return buffer.str();
|
|
}
|
|
|
|
TypePtr AbstractKeywordArg::BuildType() const {
|
|
MS_EXCEPTION_IF_NULL(arg_value_);
|
|
TypePtr type = arg_value_->BuildType();
|
|
return std::make_shared<Keyword>(arg_name_, type);
|
|
}
|
|
|
|
AbstractBasePtr AbstractKeywordArg::Clone() const {
|
|
MS_EXCEPTION_IF_NULL(arg_value_);
|
|
return std::make_shared<AbstractKeywordArg>(arg_name_, arg_value_->Clone());
|
|
}
|
|
|
|
AbstractBasePtr AbstractKeywordArg::Broaden() const {
|
|
MS_EXCEPTION_IF_NULL(arg_value_);
|
|
return std::make_shared<AbstractKeywordArg>(arg_name_, arg_value_->Broaden());
|
|
}
|
|
|
|
std::size_t AbstractKeywordArg::hash() const {
|
|
MS_EXCEPTION_IF_NULL(arg_value_);
|
|
return hash_combine({tid(), std::hash<std::string>{}(arg_name_), arg_value_->hash()});
|
|
}
|
|
|
|
std::string AbstractKeywordArg::ToString() const {
|
|
std::ostringstream buffer;
|
|
MS_EXCEPTION_IF_NULL(arg_value_);
|
|
buffer << type_name() << "(";
|
|
buffer << "key : " << arg_name_;
|
|
buffer << "value : " << arg_value_->ToString();
|
|
buffer << ")";
|
|
return buffer.str();
|
|
}
|
|
|
|
bool AbstractKeywordArg::operator==(const AbstractBase &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
|
|
if (other.isa<AbstractKeywordArg>()) {
|
|
auto other_tuple = static_cast<const AbstractKeywordArg *>(&other);
|
|
return *this == *other_tuple;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool AbstractKeywordArg::operator==(const AbstractKeywordArg &other) const {
|
|
if (&other == this) {
|
|
return true;
|
|
}
|
|
MS_EXCEPTION_IF_NULL(arg_value_);
|
|
MS_EXCEPTION_IF_NULL(other.arg_value_);
|
|
return other.arg_name_ == arg_name_ && *other.arg_value_ == *arg_value_;
|
|
}
|
|
|
|
ValuePtr AbstractKeywordArg::RealBuildValue() const {
|
|
MS_EXCEPTION_IF_NULL(arg_value_);
|
|
ValuePtr value = arg_value_->BuildValue();
|
|
MS_EXCEPTION_IF_NULL(value);
|
|
if (value->isa<AnyValue>()) {
|
|
return kAnyValue;
|
|
}
|
|
return std::make_shared<KeywordArg>(arg_name_, value);
|
|
}
|
|
|
|
std::size_t AbstractBasePtrListHash(const AbstractBasePtrList &args_spec_list) {
|
|
std::size_t hash_value = 0;
|
|
// Hashing all elements is costly, so only take at most 4 elements into account based on
|
|
// some experiments.
|
|
for (size_t i = 0; (i < args_spec_list.size()) && (i < 4); i++) {
|
|
MS_EXCEPTION_IF_NULL(args_spec_list[i]);
|
|
hash_value = hash_combine(hash_value, args_spec_list[i]->hash());
|
|
}
|
|
return hash_value;
|
|
}
|
|
|
|
bool AbstractBasePtrListDeepEqual(const AbstractBasePtrList &lhs, const AbstractBasePtrList &rhs) {
|
|
if (lhs.size() != rhs.size()) {
|
|
return false;
|
|
}
|
|
std::size_t size = lhs.size();
|
|
for (std::size_t i = 0; i < size; i++) {
|
|
MS_EXCEPTION_IF_NULL(lhs[i]);
|
|
MS_EXCEPTION_IF_NULL(rhs[i]);
|
|
if (lhs[i] == rhs[i]) {
|
|
continue;
|
|
}
|
|
if (!(*lhs[i] == *rhs[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
std::size_t AbstractBasePtrListHasher::operator()(const AbstractBasePtrList &args_spec_list) const {
|
|
return AbstractBasePtrListHash(args_spec_list);
|
|
}
|
|
|
|
bool AbstractBasePtrListEqual::operator()(const AbstractBasePtrList &lhs, const AbstractBasePtrList &rhs) const {
|
|
return AbstractBasePtrListDeepEqual(lhs, rhs);
|
|
}
|
|
} // namespace abstract
|
|
} // namespace mindspore
|