2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include "ir/OperationIndexMap.h"
22 #include "util/logging.h"
35 bool DAGChecker::verify(const Graph &graph) const noexcept
37 auto &operations = graph.operations();
40 OperationIndexMap<bool> visited;
42 [&](const OperationIndex &index, const Operation &) { visited[index] = false; });
43 OperationIndexMap<bool> on_stack = visited; // Copy from visited
45 std::function<void(const OperationIndex &index, const Operation &)> dfs_recursive =
46 [&](const OperationIndex &index, const Operation &node) -> void {
51 visited[index] = true;
52 on_stack[index] = true;
54 for (auto output : node.getOutputs() | Remove::DUPLICATED | Remove::UNDEFINED)
56 const auto &operand = graph.operands().at(output);
57 for (const auto &use : operand.getUses())
59 dfs_recursive(use, graph.operations().at(use));
63 on_stack[index] = false;
66 operations.iterate(dfs_recursive);
72 // EdgeConsistencyVerifier
75 bool EdgeChecker::verify(const Graph &graph) const noexcept
77 auto &operations = graph.operations();
79 operations.iterate([&](const OperationIndex &index, const Operation &node) {
80 for (auto operand_index : node.getInputs() | ir::Remove::UNDEFINED)
84 auto &operand = graph.operands().at(operand_index);
85 bool operand_has_use = operand.getUses().contains(index);
88 VERBOSE(EdgeChecker) << "[ERROR] EDGE MISMATCH : Missing USE edge - Operand "
89 << operand_index << " to Operation " << index << std::endl;
93 catch (const std::out_of_range &e)
95 VERBOSE(EdgeChecker) << "[ERROR] OPEARAND NOT FOUND : Operation " << index
96 << " has Operand " << operand_index
97 << ", but the operand object is not present in the graph" << std::endl;
101 for (auto operand_index : node.getOutputs() | ir::Remove::UNDEFINED)
105 auto &operand = graph.operands().at(operand_index);
106 if (operand.getDef() != index)
108 VERBOSE(EdgeChecker) << "[ERROR] EDGE MISMATCH : Missing DEF edge - Operand"
109 << operand_index << " to Operation " << index << std::endl;
113 catch (const std::out_of_range &e)
115 VERBOSE(EdgeChecker) << "[ERROR] OPEARAND NOT FOUND : Operation " << index
116 << " has Operand " << operand_index
117 << ", but the operand object is not present in the graph" << std::endl;
123 VERBOSE(EdgeChecker) << "Total Number of errors : " << errors << std::endl;
128 bool InputOutputChecker::verify(const Graph &graph) const noexcept
130 for (auto operand_ind :
131 (graph.getInputs() + graph.getOutputs()) | Remove::DUPLICATED | Remove::UNDEFINED)
133 if (!graph.operands().exist(operand_ind))
135 VERBOSE(InputOutputChecker) << "Input or Output tensor " << operand_ind << " does not exist.";
142 } // namespace verifier