forked from huawei/mindspore2022
104 lines
3.8 KiB
C++
104 lines
3.8 KiB
C++
/**
|
|
* Copyright 2021 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 "backend/common/pass/optimize_updatestate.h"
|
|
#include <memory>
|
|
#include <vector>
|
|
#include <string>
|
|
#include "base/core_ops.h"
|
|
#include "include/common/utils/utils.h"
|
|
|
|
namespace mindspore {
|
|
namespace opt {
|
|
constexpr size_t kInputIndex = 1;
|
|
constexpr size_t kAttachIndex = 2;
|
|
constexpr size_t kAdditionalAttachIndex = 3;
|
|
|
|
/**
|
|
* @brief Define a pattern for the OptimizeUpdateState.
|
|
*
|
|
* This function defines a pattern with the prim::kPrimUpdateState primitive followed by a sequence variable.
|
|
*
|
|
* @return A VectorRef representing the defined pattern.
|
|
*/
|
|
const BaseRef OptimizeUpdateState::DefinePattern() const {
|
|
// Create a sequence variable.
|
|
VarPtr Xs = std::make_shared<SeqVar>();
|
|
return VectorRef({prim::kPrimUpdateState, Xs});
|
|
}
|
|
|
|
/**
|
|
* @brief Processes the given node to optimize UpdateState operations.
|
|
*
|
|
* This function optimizes UpdateState operations by reducing unnecessary attach nodes. If the attach node is only used
|
|
* by the UpdateState operation and is not a parameter, it will be dropped. If there are changes in the attaches, a new
|
|
* UpdateState node will be created with the optimized attaches.
|
|
*
|
|
* @param func_graph The current function graph.
|
|
* @param node The node to be processed.
|
|
* @param EquivPtr Placeholder for equivalence. Not used in this context.
|
|
* @return An optimized AnfNodePtr if applicable, or nullptr if no optimization was applied.
|
|
*/
|
|
const AnfNodePtr OptimizeUpdateState::Process(const FuncGraphPtr &func_graph, const AnfNodePtr &node,
|
|
const EquivPtr &) const {
|
|
// Ensure func_graph and node are not null.
|
|
MS_EXCEPTION_IF_NULL(func_graph);
|
|
MS_EXCEPTION_IF_NULL(node);
|
|
|
|
// Cast the node to a CNode.
|
|
auto update_state = dyn_cast<CNode>(node);
|
|
MS_EXCEPTION_IF_NULL(update_state);
|
|
|
|
// If the UpdateState node doesn't have additional attaches, skip processing.
|
|
if (update_state->size() <= kAdditionalAttachIndex) {
|
|
return nullptr;
|
|
}
|
|
|
|
auto manager = func_graph->manager();
|
|
MS_EXCEPTION_IF_NULL(manager);
|
|
|
|
auto &node_users = manager->node_users();
|
|
std::vector<AnfNodePtr> new_inputs;
|
|
(void)new_inputs.emplace_back(update_state->input(0));
|
|
(void)new_inputs.emplace_back(update_state->input(kInputIndex));
|
|
(void)new_inputs.emplace_back(update_state->input(kAttachIndex));
|
|
|
|
// Process each attach and decide whether to keep it.
|
|
for (size_t i = kAdditionalAttachIndex; i < update_state->size(); ++i) {
|
|
auto &attach = update_state->input(i);
|
|
auto &users = node_users[attach];
|
|
if ((users.size() == 1) && (users.front().first == update_state) && !attach->isa<Parameter>()) {
|
|
// If the only user of attach is the UpdateState node and it's not a parameter, skip adding this attach.
|
|
continue;
|
|
}
|
|
(void)new_inputs.emplace_back(attach);
|
|
}
|
|
|
|
// If there were no changes in the attaches, return nullptr.
|
|
if (new_inputs.size() == update_state->size()) {
|
|
return nullptr;
|
|
}
|
|
|
|
// If the attaches changed, create a new UpdateState node.
|
|
auto new_update_state = func_graph->NewCNode(new_inputs);
|
|
new_update_state->set_abstract(update_state->abstract());
|
|
new_update_state->set_scope(update_state->scope());
|
|
return new_update_state;
|
|
}
|
|
|
|
} // namespace opt
|
|
} // namespace mindspore
|