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 activation_realizer.cpp
6 : * @date 23 November 2021
7 : * @brief NNTrainer graph realizer which realizes activation!=none to actual
8 : * activation node
9 : * @see https://github.com/nnstreamer/nntrainer
10 : * @author Jihoon Lee <jhoon.it.lee@samsung.com>
11 : * @bug No known bugs except for NYI items
12 : */
13 : #include "nntrainer_error.h"
14 : #include <activation_realizer.h>
15 : #include <remap_realizer.h>
16 :
17 : #include <activation_layer.h>
18 : #include <layer_node.h>
19 : #include <stdexcept>
20 : #include <unordered_map>
21 :
22 : namespace nntrainer {
23 :
24 1396 : ActivationRealizer::~ActivationRealizer() {}
25 :
26 : GraphRepresentation
27 696 : ActivationRealizer::realize(const GraphRepresentation &reference) {
28 : GraphRepresentation processed;
29 696 : processed.reserve(reference.size());
30 :
31 : std::unordered_map<std::string /**< layer_name */,
32 : std::string /**< act_layer_name */>
33 : remap_table;
34 : std::unordered_map<std::string /**< temp_layer_name */,
35 : std::string /**< layer_name */>
36 : recovery_table;
37 : std::vector<LayerNode *> act_nodes;
38 :
39 4757 : for (auto &node : reference) {
40 4062 : processed.push_back(node);
41 4062 : if (node->getType() == ActivationLayer::type) {
42 : /// realizing activation type not allowed because there is no good way to
43 : /// tell between 1. it is activation layer, 2. activation layer wants
44 : /// realization for now. later, we should have relu, sigmoid kind as layer
45 : /// type to resolve this matter, this is checked
46 : /// node->getActivationToBeRealized() but explicitly stated in order to
47 : /// make it robust, plus we might want to change the behavior
48 320 : continue;
49 : }
50 3742 : if (auto act = node->getActivationToBeRealized();
51 : act != ActivationType::ACT_NONE) {
52 279 : NNTR_THROW_IF(act == ActivationType::ACT_UNKNOWN, std::invalid_argument)
53 2 : << "unknown activation type for layer: " << node->getName();
54 :
55 278 : auto layer_name = node->getName();
56 : props::Activation act_prop;
57 278 : act_prop.set(act);
58 278 : node->setProperty({"activation=none"});
59 :
60 278 : auto act_name = layer_name + "/activation_realized";
61 278 : auto temp_name = act_name + "/temp";
62 278 : remap_table.insert({layer_name, act_name});
63 278 : recovery_table.insert({temp_name, layer_name});
64 : auto act_node =
65 556 : createLayerNode("activation", {"name=" + act_name,
66 1390 : "activation=" + to_string(act_prop)});
67 556 : act_node->setProperty({"input_layers=" + temp_name});
68 278 : processed.push_back(std::move(act_node));
69 : }
70 : }
71 : processed =
72 1390 : RemapRealizer([&remap_table](std::string &name, unsigned &idx) {
73 4471 : if (auto iter = remap_table.find(name); iter != remap_table.end()) {
74 177 : name = iter->second;
75 : }
76 4471 : })
77 1390 : .realize(processed);
78 : processed =
79 1390 : RemapRealizer([&recovery_table](std::string &name, unsigned &idx) {
80 4471 : if (auto iter = recovery_table.find(name); iter != recovery_table.end()) {
81 278 : name = iter->second;
82 : }
83 4471 : })
84 695 : .realize(processed);
85 :
86 695 : return processed;
87 1253 : }
88 : } // namespace nntrainer
|