* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include "graph/anchor.h"
#include <algorithm>
#include <cstring>
#include <sstream>
#include "graph_metadef/graph/debug/ge_util.h"
#include "framework/common/debug/ge_log.h"
#include "graph/node.h"
#include "common/util/trace_manager/trace_manager.h"
namespace {
constexpr size_t kAnchorTypeMaxLen = 1024U;
bool CanAddPeer(const af::AnchorPtr &anchor) {
if (anchor->IsTypeIdOf<af::InDataAnchor>() && (anchor->GetPeerAnchorsSize() != 0U)) {
REPORT_INNER_ERR_MSG("E18888", "anchor is type of InDataAnchor, it's peer is not empty.");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] anchor is type of InDataAnchor, it's peer is not empty.");
return false;
}
return true;
}
bool IsSameType(const af::Anchor::TYPE &lh, const af::Anchor::TYPE &rh) {
if (lh == rh) {
return true;
}
return (strncmp(lh, rh, kAnchorTypeMaxLen) == 0);
}
};
namespace af {
class AnchorImpl {
public:
AnchorImpl(const NodePtr &owner_node, const int32_t idx);
~AnchorImpl() = default;
size_t GetPeerAnchorsSize() const;
Anchor::Vistor<AnchorPtr> GetPeerAnchors(const std::shared_ptr<ConstAnchor> &anchor_ptr) const;
std::vector<Anchor *> GetPeerAnchorsPtr() const;
AnchorPtr GetFirstPeerAnchor() const;
NodePtr GetOwnerNode() const;
Node *GetOwnerNodeBarePtr() const;
int32_t GetIdx() const;
void SetIdx(const int32_t index);
private:
std::vector<std::weak_ptr<Anchor>> peer_anchors_;
std::weak_ptr<Node> owner_node_;
Node *const owner_node_ptr_;
int32_t idx_;
friend class Anchor;
friend class OutControlAnchor;
friend class InControlAnchor;
friend class OutDataAnchor;
friend class InDataAnchor;
};
AnchorImpl::AnchorImpl(const NodePtr &owner_node, const int32_t idx)
: owner_node_(owner_node), owner_node_ptr_(owner_node_.lock().get()), idx_(idx) {}
size_t AnchorImpl::GetPeerAnchorsSize() const {
return peer_anchors_.size();
}
Anchor::Vistor<AnchorPtr> AnchorImpl::GetPeerAnchors(
const std::shared_ptr<ConstAnchor> &anchor_ptr) const {
std::vector<AnchorPtr> ret;
ret.resize(peer_anchors_.size());
(void)std::transform(peer_anchors_.begin(), peer_anchors_.end(), ret.begin(),
[] (const std::weak_ptr<Anchor>& anchor) {
return anchor.lock();
});
return Anchor::Vistor<AnchorPtr>(anchor_ptr, ret);
}
std::vector<Anchor *> AnchorImpl::GetPeerAnchorsPtr() const {
std::vector<Anchor *> ret;
ret.resize(peer_anchors_.size());
(void) std::transform(peer_anchors_.begin(), peer_anchors_.end(), ret.begin(),
[](const std::weak_ptr<Anchor> &anchor) { return anchor.lock().get(); });
return ret;
}
AnchorPtr AnchorImpl::GetFirstPeerAnchor() const {
if (peer_anchors_.empty()) {
return nullptr;
} else {
return Anchor::DynamicAnchorCast<Anchor>(peer_anchors_.begin()->lock());
}
}
NodePtr AnchorImpl::GetOwnerNode() const {
return owner_node_.lock();
}
Node *AnchorImpl::GetOwnerNodeBarePtr() const {
return owner_node_ptr_;
}
int32_t AnchorImpl::GetIdx() const { return idx_; }
void AnchorImpl::SetIdx(const int32_t index) { idx_ = index; }
Anchor::Anchor(const NodePtr &owner_node, const int32_t idx)
: enable_shared_from_this(), impl_(ComGraphMakeShared<AnchorImpl>(owner_node, idx)) {}
Anchor::~Anchor() = default;
bool Anchor::IsTypeOf(const TYPE type) const {
return strncmp(Anchor::TypeOf<Anchor>(), type, kAnchorTypeMaxLen) == 0;
}
bool Anchor::IsTypeIdOf(const TypeId& type) const {
return ge::GetTypeId<Anchor>() == type;
}
Anchor::TYPE Anchor::GetSelfType() const {
return TypeOf<Anchor>();
}
size_t Anchor::GetPeerAnchorsSize() const {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
return 0UL;
}
return impl_->GetPeerAnchorsSize();
}
Anchor::Vistor<AnchorPtr> Anchor::GetPeerAnchors() const {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
const std::vector<AnchorPtr> ret;
return Anchor::Vistor<AnchorPtr>(shared_from_this(), ret);
}
return impl_->GetPeerAnchors(shared_from_this());
}
std::vector<Anchor *> Anchor::GetPeerAnchorsPtr() const {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
std::vector<Anchor *> ret;
return ret;
}
return impl_->GetPeerAnchorsPtr();
}
AnchorPtr Anchor::GetFirstPeerAnchor() const {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
return nullptr;
}
return impl_->GetFirstPeerAnchor();
}
NodePtr Anchor::GetOwnerNode() const {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
return nullptr;
}
return impl_->GetOwnerNode();
}
Node *Anchor::GetOwnerNodeBarePtr() const {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
return nullptr;
}
return impl_->GetOwnerNodeBarePtr();
}
void Anchor::UnlinkAll() noexcept {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
return;
}
if (!impl_->peer_anchors_.empty()) {
do {
const auto peer_anchor_ptr = impl_->peer_anchors_.begin()->lock();
(void)Unlink(peer_anchor_ptr);
} while (!impl_->peer_anchors_.empty());
}
}
graphStatus Anchor::Unlink(const AnchorPtr &peer) {
if (peer == nullptr) {
REPORT_INNER_ERR_MSG("E18888", "param peer is nullptr, check invalid.");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] peer anchor is invalid.");
return ge::GRAPH_FAILED;
}
GE_CHK_BOOL_RET_STATUS(impl_ != nullptr, ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr");
const auto it = std::find_if(impl_->peer_anchors_.begin(), impl_->peer_anchors_.end(),
[peer](const std::weak_ptr<Anchor> &an) {
const auto anchor = an.lock();
return peer->Equal(anchor);
});
if (it == impl_->peer_anchors_.end()) {
GELOGW("[Check][Param] Unlink failed , as this anchor is not connected to peer.");
return ge::GRAPH_FAILED;
}
const auto it_peer = std::find_if(peer->impl_->peer_anchors_.begin(), peer->impl_->peer_anchors_.end(),
[this](const std::weak_ptr<Anchor> &an) {
const auto anchor = an.lock();
return Equal(anchor);
});
GE_CHK_BOOL_RET_STATUS(it_peer != peer->impl_->peer_anchors_.end(), ge::GRAPH_FAILED,
"[Check][Param] peer(%s, %d) is not connected to this anchor(%s, %d)",
peer->GetOwnerNode()->GetName().c_str(), peer->GetIdx(),
this->GetOwnerNode()->GetName().c_str(), this->GetIdx());
if ((this->GetOwnerNode() != nullptr) && (peer->GetOwnerNode() != nullptr)) {
TRACE_GEN_RECORD(TraceManager::GetTraceHeader(), "delete", TraceManager::GetOutGraphName(),
this->GetOwnerNode()->GetName(), "output:" << this->GetIdx(), "", "",
peer->GetOwnerNode()->GetName() << ":input:" << peer->GetIdx());
}
(void)impl_->peer_anchors_.erase(it);
(void)peer->impl_->peer_anchors_.erase(it_peer);
return GRAPH_SUCCESS;
}
graphStatus Anchor::Insert(const AnchorPtr &old_peer, const AnchorPtr &first_peer, const AnchorPtr &second_peer) {
GE_CHECK_NOTNULL(old_peer);
GE_CHECK_NOTNULL(first_peer);
GE_CHECK_NOTNULL(second_peer);
GE_CHECK_NOTNULL(impl_);
if (!IsSameType(old_peer->GetSelfType(), first_peer->GetSelfType())) {
REPORT_INNER_ERR_MSG("E18888", "the type of old_peer[%s] and first_peer[%s] is not the same.",
old_peer->GetSelfType(), first_peer->GetSelfType());
GELOGE(ge::GRAPH_FAILED, "[Check][Param] the type of old_peer[%s] and first_peer[%s] is not the same.",
old_peer->GetSelfType(), first_peer->GetSelfType());
return ge::GRAPH_FAILED;
}
if (!IsSameType(second_peer->GetSelfType(), this->GetSelfType())) {
REPORT_INNER_ERR_MSG("E18888", "the type of second_peer[%s] and current anchor[%s] is not the same.",
second_peer->GetSelfType(), this->GetSelfType());
GELOGE(ge::GRAPH_FAILED, "[Check][Param] the type of second_peer[%s] and current anchor[%s] is not the same.",
second_peer->GetSelfType(), this->GetSelfType());
return ge::GRAPH_FAILED;
}
if ((!CanAddPeer(first_peer)) || (!CanAddPeer(second_peer))) {
REPORT_INNER_ERR_MSG("E18888", "first_peer[%s] or second_peer[%s] check failed", first_peer->GetSelfType(),
second_peer->GetSelfType());
GELOGE(ge::GRAPH_FAILED, "[Check][Param] first_peer[%s] or second_peer[%s] check failed",
first_peer->GetSelfType(), second_peer->GetSelfType());
return ge::GRAPH_FAILED;
}
const auto this_it = std::find_if(impl_->peer_anchors_.begin(), impl_->peer_anchors_.end(),
[old_peer](const std::weak_ptr<Anchor> &an) {
const auto anchor = an.lock();
return old_peer->Equal(anchor);
});
GE_CHK_BOOL_RET_STATUS(this_it != impl_->peer_anchors_.end(), ge::GRAPH_FAILED,
"[Check][Param] this anchor(%s, %d) is not connected to old_peer(%s, %d)",
this->GetOwnerNode()->GetName().c_str(), this->GetIdx(),
old_peer->GetOwnerNode()->GetName().c_str(), old_peer->GetIdx());
const auto old_it = std::find_if(old_peer->impl_->peer_anchors_.begin(), old_peer->impl_->peer_anchors_.end(),
[this](const std::weak_ptr<Anchor> &an) {
const auto anchor = an.lock();
return Equal(anchor);
});
GE_CHK_BOOL_RET_STATUS(old_it != old_peer->impl_->peer_anchors_.end(), ge::GRAPH_FAILED,
"[Check][Param] old_peer(%s, %d) is not connected to this anchor(%s, %d)",
old_peer->GetOwnerNode()->GetName().c_str(), old_peer->GetIdx(),
this->GetOwnerNode()->GetName().c_str(), this->GetIdx());
*this_it = first_peer;
first_peer->impl_->peer_anchors_.push_back(shared_from_this());
*old_it = second_peer;
second_peer->impl_->peer_anchors_.push_back(old_peer);
return GRAPH_SUCCESS;
}
graphStatus Anchor::ReplacePeer(const AnchorPtr &old_peer, const AnchorPtr &new_peer) {
GE_CHECK_NOTNULL(old_peer);
GE_CHECK_NOTNULL(new_peer);
GE_CHECK_NOTNULL(impl_);
if (!IsSameType(old_peer->GetSelfType(), new_peer->GetSelfType())) {
REPORT_INNER_ERR_MSG("E18888", "the type of old_peer[%s] and new_peer[%s] is not the same.",
old_peer->GetSelfType(), new_peer->GetSelfType());
GELOGE(ge::GRAPH_FAILED, "[Check][Param] the type of old_peer[%s] and new_peer[%s] is not the same.",
old_peer->GetSelfType(), new_peer->GetSelfType());
return ge::GRAPH_FAILED;
}
if (!CanAddPeer(new_peer)) {
REPORT_INNER_ERR_MSG("E18888", "new_peer[%s] check failed.", new_peer->GetSelfType());
GELOGE(ge::GRAPH_FAILED, "[Check][Param] new_peer[%s] check failed.", new_peer->GetSelfType());
return ge::GRAPH_FAILED;
}
const auto this_it = std::find_if(this->impl_->peer_anchors_.begin(), this->impl_->peer_anchors_.end(),
[old_peer](const std::weak_ptr<Anchor> &an) {
const auto anchor = an.lock();
return old_peer->Equal(anchor);
});
if (this_it == this->impl_->peer_anchors_.end()) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] this anchor(%s, %d) is not connected to old_peer(%s, %d)",
this->GetOwnerNode()->GetName().c_str(), this->GetIdx(),
old_peer->GetOwnerNode()->GetName().c_str(), old_peer->GetIdx());
return ge::GRAPH_FAILED;
}
const auto old_it = std::find_if(old_peer->impl_->peer_anchors_.begin(), old_peer->impl_->peer_anchors_.end(),
[this](const std::weak_ptr<Anchor> &an) {
const auto anchor = an.lock();
return this->Equal(anchor);
});
*this_it = new_peer;
(void)old_peer->impl_->peer_anchors_.erase(old_it);
new_peer->impl_->peer_anchors_.push_back(shared_from_this());
return GRAPH_SUCCESS;
}
bool Anchor::IsLinkedWith(const AnchorPtr &peer) const {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
return false;
}
const auto it = std::find_if(impl_->peer_anchors_.begin(), impl_->peer_anchors_.end(),
[peer](const std::weak_ptr<Anchor> &an) {
const auto anchor = an.lock();
if (peer == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] this old peer anchor is nullptr");
return false;
}
return peer->Equal(anchor);
});
return (it != impl_->peer_anchors_.end());
}
int32_t Anchor::GetIdx() const {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
return 0;
}
return impl_->GetIdx();
}
void Anchor::SetIdx(const int32_t index) {
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "[Check][Param] impl_ of anchor is nullptr.");
return;
}
impl_->SetIdx(index);
}
DataAnchor::DataAnchor(const NodePtr &owner_node, const int32_t idx) : Anchor(owner_node, idx) {}
bool DataAnchor::IsTypeOf(const TYPE type) const {
if (strncmp(Anchor::TypeOf<DataAnchor>(), type, kAnchorTypeMaxLen) == 0) {
return true;
}
return Anchor::IsTypeOf(type);
}
Anchor::TYPE DataAnchor::GetSelfType() const {
return Anchor::TypeOf<DataAnchor>();
}
bool DataAnchor::IsTypeIdOf(const TypeId &type) const {
if (ge::GetTypeId<DataAnchor>() == type) {
return true;
}
return Anchor::IsTypeIdOf(type);
}
InDataAnchor::InDataAnchor(const NodePtr &owner_node, const int32_t idx) : DataAnchor(owner_node, idx) {}
OutDataAnchorPtr InDataAnchor::GetPeerOutAnchor() const {
if ((impl_ == nullptr) || impl_->peer_anchors_.empty()) {
return nullptr;
} else {
return Anchor::DynamicAnchorCast<OutDataAnchor>(impl_->peer_anchors_.begin()->lock());
}
}
graphStatus InDataAnchor::LinkFrom(const OutDataAnchorPtr &src) {
if ((src == nullptr) || (src->impl_ == nullptr) ||
(impl_ == nullptr) || (!impl_->peer_anchors_.empty())) {
REPORT_INNER_ERR_MSG("E18888", "src anchor is invalid or the peerAnchors is not empty.");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] src anchor is invalid or the peerAnchors is not empty.");
return ge::GRAPH_FAILED;
}
impl_->peer_anchors_.push_back(src);
src->impl_->peer_anchors_.push_back(shared_from_this());
if ((src->impl_->GetOwnerNodeBarePtr() == nullptr) || (impl_->GetOwnerNodeBarePtr() == nullptr)) {
GELOGW("[Check][Param] src->impl_->GetOwnerNode() or impl_->GetOwnerNode() is null.");
} else {
TRACE_GEN_RECORD(TraceManager::GetTraceHeader(), "add", TraceManager::GetOutGraphName(),
src->impl_->GetOwnerNode()->GetName(), "output:" << src->impl_->GetIdx(), "", "",
impl_->GetOwnerNode()->GetName() << ":input:" << impl_->GetIdx());
}
return GRAPH_SUCCESS;
}
bool InDataAnchor::Equal(const AnchorPtr anchor) const {
const auto in_data_anchor = Anchor::DynamicAnchorCast<InDataAnchor>(anchor);
if (in_data_anchor != nullptr) {
if ((GetOwnerNodeBarePtr() == in_data_anchor->GetOwnerNodeBarePtr()) && (GetIdx() == in_data_anchor->GetIdx())) {
return true;
}
}
return false;
}
bool InDataAnchor::IsTypeOf(const TYPE type) const {
if (strncmp(Anchor::TypeOf<InDataAnchor>(), type, kAnchorTypeMaxLen) == 0) {
return true;
}
return DataAnchor::IsTypeOf(type);
}
Anchor::TYPE InDataAnchor::GetSelfType() const {
return Anchor::TypeOf<InDataAnchor>();
}
bool InDataAnchor::IsTypeIdOf(const TypeId &type) const {
if (ge::GetTypeId<InDataAnchor>() == type) {
return true;
}
return DataAnchor::IsTypeIdOf(type);
}
OutDataAnchor::OutDataAnchor(const NodePtr &owner_node, const int32_t idx) : DataAnchor(owner_node, idx) {}
OutDataAnchor::Vistor<InDataAnchorPtr> OutDataAnchor::GetPeerInDataAnchors() const {
std::vector<InDataAnchorPtr> ret;
if (impl_ != nullptr) {
ret.reserve(impl_->peer_anchors_.size());
for (const auto &anchor : impl_->peer_anchors_) {
const auto in_data_anchor = Anchor::DynamicAnchorCast<InDataAnchor>(anchor.lock());
if (in_data_anchor != nullptr) {
ret.push_back(in_data_anchor);
}
}
}
return OutDataAnchor::Vistor<InDataAnchorPtr>(shared_from_this(), ret);
}
std::vector<InDataAnchor *> OutDataAnchor::GetPeerInDataAnchorsPtr() const {
std::vector<InDataAnchor *> ret;
if (impl_ != nullptr) {
ret.reserve(impl_->peer_anchors_.size());
for (const auto &anchor : impl_->peer_anchors_) {
const auto in_data_anchor = Anchor::DynamicAnchorPtrCast<InDataAnchor>(anchor.lock().get());
if (in_data_anchor != nullptr) {
ret.push_back(in_data_anchor);
}
}
}
return ret;
}
uint32_t OutDataAnchor::GetPeerInDataNodesSize() const {
uint32_t out_nums = 0U;
if (impl_ != nullptr) {
for (const auto &anchor : impl_->peer_anchors_) {
const auto in_data_anchor = Anchor::DynamicAnchorCast<InDataAnchor>(anchor.lock());
if ((in_data_anchor != nullptr) && (in_data_anchor->GetOwnerNodeBarePtr() != nullptr)) {
out_nums++;
}
}
}
return out_nums;
}
OutDataAnchor::Vistor<InControlAnchorPtr> OutDataAnchor::GetPeerInControlAnchors() const {
std::vector<InControlAnchorPtr> ret;
if (impl_ != nullptr) {
ret.reserve(impl_->peer_anchors_.size());
for (const auto &anchor : impl_->peer_anchors_) {
const auto in_control_anchor = Anchor::DynamicAnchorCast<InControlAnchor>(anchor.lock());
if (in_control_anchor != nullptr) {
ret.push_back(in_control_anchor);
}
}
}
return OutDataAnchor::Vistor<InControlAnchorPtr>(shared_from_this(), ret);
}
graphStatus OutDataAnchor::LinkTo(const InDataAnchorPtr &dest) {
if ((dest == nullptr) || (dest->impl_ == nullptr) ||
(!dest->impl_->peer_anchors_.empty())) {
REPORT_INNER_ERR_MSG("E18888", "dest anchor is nullptr or the peerAnchors is not empty.");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] dest anchor is nullptr or the peerAnchors is not empty.");
return ge::GRAPH_FAILED;
}
if (impl_ == nullptr) {
REPORT_INNER_ERR_MSG("E18888", "anchor param is nullptr, check invalid");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] owner anchor is invalid.");
return ge::GRAPH_FAILED;
}
impl_->peer_anchors_.push_back(dest);
dest->impl_->peer_anchors_.push_back(shared_from_this());
TRACE_GEN_RECORD(TraceManager::GetTraceHeader(), "add", TraceManager::GetOutGraphName(),
impl_->GetOwnerNode()->GetName(), "output:" << impl_->GetIdx(), "", "",
dest->impl_->GetOwnerNode()->GetName() << ":input:" << dest->impl_->GetIdx());
return GRAPH_SUCCESS;
}
graphStatus OutDataAnchor::LinkTo(const InControlAnchorPtr &dest) {
if ((dest == nullptr) || (dest->impl_ == nullptr)) {
REPORT_INNER_ERR_MSG("E18888", "param dest is nullptr, check invalid");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] dest anchor is invalid.");
return ge::GRAPH_FAILED;
}
if (impl_ == nullptr) {
GELOGE(ge::GRAPH_FAILED, "src anchor is invalid.");
return ge::GRAPH_FAILED;
}
impl_->peer_anchors_.push_back(dest);
dest->impl_->peer_anchors_.push_back(shared_from_this());
TRACE_GEN_RECORD(TraceManager::GetTraceHeader(), "add", TraceManager::GetOutGraphName(),
impl_->GetOwnerNode()->GetName(), "output:" << impl_->GetIdx(), "", "",
dest->impl_->GetOwnerNode()->GetName() << ":input:" << dest->impl_->GetIdx());
return GRAPH_SUCCESS;
}
graphStatus OutControlAnchor::LinkTo(const InDataAnchorPtr &dest) {
if ((dest == nullptr) || (dest->impl_ == nullptr)) {
REPORT_INNER_ERR_MSG("E18888", "param dest is nullptr, check invalid");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] dest anchor is invalid.");
return ge::GRAPH_FAILED;
}
if (impl_ == nullptr) {
REPORT_INNER_ERR_MSG("E18888", "anchor param is nullptr, check invalid");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] owner anchor is invalid.");
return ge::GRAPH_FAILED;
}
impl_->peer_anchors_.push_back(dest);
dest->impl_->peer_anchors_.push_back(shared_from_this());
TRACE_GEN_RECORD(TraceManager::GetTraceHeader(), "add", TraceManager::GetOutGraphName(),
impl_->GetOwnerNode()->GetName(), "output:" << impl_->GetIdx(), "", "",
dest->impl_->GetOwnerNode()->GetName() << ":input:" << dest->impl_->GetIdx());
return GRAPH_SUCCESS;
}
bool OutDataAnchor::Equal(const AnchorPtr anchor) const {
CHECK_FALSE_EXEC(anchor != nullptr, return false);
const auto out_data_anchor = Anchor::DynamicAnchorCast<OutDataAnchor>(anchor);
if (out_data_anchor != nullptr) {
if ((GetOwnerNodeBarePtr() == out_data_anchor->GetOwnerNodeBarePtr()) && (GetIdx() == out_data_anchor->GetIdx())) {
return true;
}
}
return false;
}
bool OutDataAnchor::IsTypeOf(const TYPE type) const {
if (strncmp(Anchor::TypeOf<OutDataAnchor>(), type, kAnchorTypeMaxLen) == 0) {
return true;
}
return DataAnchor::IsTypeOf(type);
}
Anchor::TYPE OutDataAnchor::GetSelfType() const {
return Anchor::TypeOf<OutDataAnchor>();
}
bool OutDataAnchor::IsTypeIdOf(const TypeId &type) const {
if (ge::GetTypeId<OutDataAnchor>() == type) {
return true;
}
return DataAnchor::IsTypeIdOf(type);
}
ControlAnchor::ControlAnchor(const NodePtr &owner_node) : Anchor(owner_node, -1) {}
ControlAnchor::ControlAnchor(const NodePtr &owner_node, const int32_t idx) : Anchor(owner_node, idx) {}
bool ControlAnchor::IsTypeOf(const TYPE type) const {
if (strncmp(Anchor::TypeOf<ControlAnchor>(), type, kAnchorTypeMaxLen) == 0) {
return true;
}
return Anchor::IsTypeOf(type);
}
Anchor::TYPE ControlAnchor::GetSelfType() const {
return Anchor::TypeOf<ControlAnchor>();
}
bool ControlAnchor::IsTypeIdOf(const TypeId &type) const {
if (ge::GetTypeId<ControlAnchor>() == type) {
return true;
}
return Anchor::IsTypeIdOf(type);
}
InControlAnchor::InControlAnchor(const NodePtr &owner_node) : ControlAnchor(owner_node) {}
InControlAnchor::InControlAnchor(const NodePtr &owner_node, const int32_t idx) : ControlAnchor(owner_node, idx) {}
InControlAnchor::Vistor<OutControlAnchorPtr> InControlAnchor::GetPeerOutControlAnchors() const {
std::vector<OutControlAnchorPtr> ret;
if (impl_ != nullptr) {
ret.reserve(impl_->peer_anchors_.size());
for (const auto &anchor : impl_->peer_anchors_) {
const auto out_control_anchor = Anchor::DynamicAnchorCast<OutControlAnchor>(anchor.lock());
if (out_control_anchor != nullptr) {
ret.push_back(out_control_anchor);
}
}
}
return InControlAnchor::Vistor<OutControlAnchorPtr>(shared_from_this(), ret);
}
std::vector<OutControlAnchor *> InControlAnchor::GetPeerOutControlAnchorsPtr() const {
std::vector<OutControlAnchor *> ret;
if (impl_ != nullptr) {
ret.reserve(impl_->peer_anchors_.size());
for (const auto &anchor : impl_->peer_anchors_) {
const auto out_control_anchor = Anchor::DynamicAnchorPtrCast<OutControlAnchor>(anchor.lock().get());
if (out_control_anchor != nullptr) {
ret.push_back(out_control_anchor);
}
}
}
return ret;
}
bool InControlAnchor::IsPeerOutAnchorsEmpty() const {
if (impl_ == nullptr) {
return false;
}
return impl_->peer_anchors_.empty();
}
InControlAnchor::Vistor<OutDataAnchorPtr> InControlAnchor::GetPeerOutDataAnchors() const {
std::vector<OutDataAnchorPtr> ret;
if (impl_ != nullptr) {
for (const auto &anchor : impl_->peer_anchors_) {
const auto out_data_anchor = Anchor::DynamicAnchorCast<OutDataAnchor>(anchor.lock());
if (out_data_anchor != nullptr) {
ret.push_back(out_data_anchor);
}
}
}
return InControlAnchor::Vistor<OutDataAnchorPtr>(shared_from_this(), ret);
}
graphStatus InControlAnchor::LinkFrom(const OutControlAnchorPtr &src) {
if ((src == nullptr) || (src->impl_ == nullptr)) {
REPORT_INNER_ERR_MSG("E18888", "param src is nullptr, check invalid");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] src anchor is invalid.");
return ge::GRAPH_FAILED;
}
if (impl_ == nullptr) {
REPORT_INNER_ERR_MSG("E18888", "anchor param is nullptr, check invalid");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] owner anchor is invalid.");
return ge::GRAPH_FAILED;
}
impl_->peer_anchors_.push_back(src);
src->impl_->peer_anchors_.push_back(shared_from_this());
TRACE_GEN_RECORD(TraceManager::GetTraceHeader(), "add", TraceManager::GetOutGraphName(),
src->impl_->GetOwnerNode()->GetName(), "output:" << src->impl_->GetIdx(), "", "",
impl_->GetOwnerNode()->GetName() << ":input:" << impl_->GetIdx());
return GRAPH_SUCCESS;
}
bool InControlAnchor::Equal(const AnchorPtr anchor) const {
CHECK_FALSE_EXEC(anchor != nullptr, REPORT_INNER_ERR_MSG("E18888", "param anchor is nullptr, check invalid");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] anchor is invalid."); return false);
const auto in_control_anchor = Anchor::DynamicAnchorCast<InControlAnchor>(anchor);
if (in_control_anchor != nullptr) {
if (GetOwnerNodeBarePtr() == in_control_anchor->GetOwnerNodeBarePtr()) {
return true;
}
}
return false;
}
bool InControlAnchor::IsTypeOf(const TYPE type) const {
if (strncmp(Anchor::TypeOf<InControlAnchor>(), type, kAnchorTypeMaxLen) == 0) {
return true;
}
return ControlAnchor::IsTypeOf(type);
}
Anchor::TYPE InControlAnchor::GetSelfType() const {
return Anchor::TypeOf<InControlAnchor>();
}
bool InControlAnchor::IsTypeIdOf(const TypeId &type) const {
if (ge::GetTypeId<InControlAnchor>() == type) {
return true;
}
return ControlAnchor::IsTypeIdOf(type);
}
OutControlAnchor::OutControlAnchor(const NodePtr &owner_node) : ControlAnchor(owner_node) {}
OutControlAnchor::OutControlAnchor(const NodePtr &owner_node, const int32_t idx) : ControlAnchor(owner_node, idx) {}
OutControlAnchor::Vistor<InControlAnchorPtr> OutControlAnchor::GetPeerInControlAnchors() const {
std::vector<InControlAnchorPtr> ret;
if (impl_ != nullptr) {
ret.reserve(impl_->peer_anchors_.size());
for (const auto &anchor : impl_->peer_anchors_) {
const auto in_control_anchor = Anchor::DynamicAnchorCast<InControlAnchor>(anchor.lock());
if (in_control_anchor != nullptr) {
ret.push_back(in_control_anchor);
}
}
}
return OutControlAnchor::Vistor<InControlAnchorPtr>(shared_from_this(), ret);
}
std::vector<InControlAnchor *> OutControlAnchor::GetPeerInControlAnchorsPtr() const {
std::vector<InControlAnchor *> ret;
if (impl_ != nullptr) {
ret.reserve(impl_->peer_anchors_.size());
for (const auto &anchor : impl_->peer_anchors_) {
const auto in_control_anchor = Anchor::DynamicAnchorPtrCast<InControlAnchor>(anchor.lock().get());
if (in_control_anchor != nullptr) {
ret.push_back(in_control_anchor);
}
}
}
return ret;
}
OutControlAnchor::Vistor<InDataAnchorPtr> OutControlAnchor::GetPeerInDataAnchors() const {
std::vector<InDataAnchorPtr> ret;
if (impl_ != nullptr) {
for (const auto &anchor : impl_->peer_anchors_) {
const auto in_data_anchor = Anchor::DynamicAnchorCast<InDataAnchor>(anchor.lock());
if (in_data_anchor != nullptr) {
ret.push_back(in_data_anchor);
}
}
}
return OutControlAnchor::Vistor<InDataAnchorPtr>(shared_from_this(), ret);
}
graphStatus OutControlAnchor::LinkTo(const InControlAnchorPtr &dest) {
if ((dest == nullptr) || (dest->impl_ == nullptr)) {
REPORT_INNER_ERR_MSG("E18888", "param dest is nullptr, check invalid");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] dest anchor is invalid.");
return ge::GRAPH_FAILED;
}
if (impl_ == nullptr) {
REPORT_INNER_ERR_MSG("E18888", "anchor param is nullptr, check invalid");
GELOGE(ge::GRAPH_FAILED, "[Check][Param] owner anchor is invalid.");
return ge::GRAPH_FAILED;
}
impl_->peer_anchors_.push_back(dest);
dest->impl_->peer_anchors_.push_back(shared_from_this());
TRACE_GEN_RECORD(TraceManager::GetTraceHeader(), "add", TraceManager::GetOutGraphName(),
impl_->GetOwnerNode()->GetName(), "output:" << impl_->GetIdx(), "", "",
dest->impl_->GetOwnerNode()->GetName() << ":input:" << dest->impl_->GetIdx());
return GRAPH_SUCCESS;
}
bool OutControlAnchor::Equal(const AnchorPtr anchor) const {
const auto out_control_anchor = Anchor::DynamicAnchorCast<OutControlAnchor>(anchor);
if (out_control_anchor != nullptr) {
if (GetOwnerNodeBarePtr() == out_control_anchor->GetOwnerNodeBarePtr()) {
return true;
}
}
return false;
}
bool OutControlAnchor::IsTypeOf(const TYPE type) const {
if (strncmp(Anchor::TypeOf<OutControlAnchor>(), type, kAnchorTypeMaxLen) == 0) {
return true;
}
return ControlAnchor::IsTypeOf(type);
}
Anchor::TYPE OutControlAnchor::GetSelfType() const {
return Anchor::TypeOf<OutControlAnchor>();
}
bool OutControlAnchor::IsTypeIdOf(const TypeId &type) const {
if (ge::GetTypeId<OutControlAnchor>() == type) {
return true;
}
return ControlAnchor::IsTypeIdOf(type);
}
}
namespace ge {
template<>
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY TypeId GetTypeId<af::Anchor>() {
return reinterpret_cast<TypeId>(1);
}
template<>
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY TypeId GetTypeId<af::DataAnchor>() {
return reinterpret_cast<TypeId>(2);
}
template<>
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY TypeId GetTypeId<af::ControlAnchor>() {
return reinterpret_cast<TypeId>(3);
}
template<>
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY TypeId GetTypeId<af::InDataAnchor>() {
return reinterpret_cast<TypeId>(4);
}
template<>
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY TypeId GetTypeId<af::OutDataAnchor>() {
return reinterpret_cast<TypeId>(5);
}
template<>
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY TypeId GetTypeId<af::InControlAnchor>() {
return reinterpret_cast<TypeId>(6);
}
template<>
GE_FUNC_DEV_VISIBILITY GE_FUNC_HOST_VISIBILITY TypeId GetTypeId<af::OutControlAnchor>() {
return reinterpret_cast<TypeId>(7);
}
}