Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : /**
3 : * Copyright (C) 2021 Jihoon Lee <jhoon.it.lee@samsung.com>
4 : *
5 : * @file previous_input_realizer.cpp
6 : * @date 18 November 2021
7 : * @brief NNTrainer graph realizer which connects input to previous one if empty
8 : * @see https://github.com/nnstreamer/nntrainer
9 : * @author Jihoon Lee <jhoon.it.lee@samsung.com>
10 : * @bug No known bugs except for NYI items
11 : */
12 : #include <algorithm>
13 : #include <compiler_fwd.h>
14 : #include <memory>
15 : #include <stdexcept>
16 : #include <vector>
17 :
18 : #include <connection.h>
19 : #include <layer_node.h>
20 : #include <nntrainer_log.h>
21 : #include <previous_input_realizer.h>
22 :
23 : namespace nntrainer {
24 :
25 753 : PreviousInputRealizer::PreviousInputRealizer(
26 753 : const std::vector<Connection> &identified_inputs_) :
27 753 : identified_inputs(identified_inputs_) {}
28 :
29 1502 : PreviousInputRealizer::~PreviousInputRealizer() {}
30 :
31 : GraphRepresentation
32 753 : PreviousInputRealizer::realize(const GraphRepresentation &reference) {
33 753 : GraphRepresentation processed(reference.begin(), reference.end());
34 :
35 : /**
36 : * @brief for node has input connection, below function determines if the node
37 : * should be input node or add input_layers from previous layer
38 : *
39 : */
40 1586 : auto is_actually_an_input_node = [this](const LayerNode &node) {
41 2000 : return node.hasInputShapeProperty() or
42 : std::any_of(
43 414 : identified_inputs.begin(), identified_inputs.end(),
44 546 : [&node](auto &conn) { return node.getName() == conn.getName(); });
45 753 : };
46 :
47 4952 : for (auto iter = processed.begin(); iter != processed.end(); ++iter) {
48 : auto &node = *iter;
49 4202 : if (node->getNumInputConnections() != 0) {
50 2616 : continue;
51 : }
52 :
53 1586 : if (is_actually_an_input_node(*node)) {
54 1175 : continue;
55 : }
56 :
57 : /**
58 : * @brief Weight layer can't have a previous input
59 : *
60 : */
61 411 : if (node->getType() == "weight")
62 0 : continue;
63 :
64 411 : NNTR_THROW_IF(iter == processed.begin(), std::invalid_argument)
65 : << "First node must be identified as an input if it is qualified to be "
66 : "input, name: "
67 6 : << node->getName();
68 :
69 : auto &prev_node = *(iter - 1);
70 816 : ml_logi(
71 : "%s is identified as a non-input node and default input layer(%s) is "
72 : "being set ",
73 : node->getName().c_str(), prev_node->getName().c_str());
74 :
75 1632 : node->setProperty({"input_layers=" + prev_node->getName()});
76 : }
77 :
78 750 : return processed;
79 411 : }
80 :
81 : } // namespace nntrainer
|