0360b9fef1616d385f88c9a518e174e942205eb0
[platform/core/ml/nnfw.git] / compiler / locomotiv / src / Node / ConstGen.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
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
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "NodeExecution.h"
18
19 #include "NodeDataImpl.h"
20 #include "NodeDomain.h"
21
22 #include <nncc/core/ADT/tensor/Shape.h>
23 #include <nncc/core/ADT/tensor/Buffer.h>
24 #include <nncc/core/ADT/tensor/IndexEnumerator.h>
25 #include <nncc/core/ADT/tensor/LexicalLayout.h>
26
27 #include <stdexcept>
28 #include <cassert>
29
30 using nncc::core::ADT::tensor::Index;
31 using nncc::core::ADT::tensor::IndexEnumerator;
32 using nncc::core::ADT::tensor::Shape;
33 using nncc::core::ADT::tensor::LexicalLayout;
34 using nncc::core::ADT::tensor::make_buffer;
35
36 namespace
37 {
38
39 /**
40  * @brief Get offset based on given shape and index. Assume lexical layout.
41  *
42  * examples)
43  * For shape = {3, 4} and index = {1, 2},
44  *     offset would be 6 ( = 1 * (4) + 2 )
45  * For shape = {2, 3, 4} and index = {1, 0, 2},
46  *     offset would be 14 ( = 1 * (3*4) + 0 *(4) + 2 )
47  */
48 inline uint32_t offset_by_index(const Shape &shape, const Index &index)
49 {
50   static const nncc::core::ADT::tensor::LexicalLayout l;
51   return l.offset(shape, index);
52 }
53
54 } // namespace
55
56 namespace locomotiv
57 {
58
59 void NodeExecution::execute(loco::ConstGen *constgen)
60 {
61   uint32_t volume = 1;
62
63   Shape shape;
64   shape.resize(constgen->rank());
65   for (uint32_t i = 0; i < shape.rank(); ++i)
66   {
67     shape.dim(i) = constgen->dim(i).value();
68     volume *= shape.dim(i);
69   }
70
71   std::unique_ptr<NodeData> data = nullptr;
72
73   switch (constgen->dtype())
74   {
75     case loco::DataType::S32:
76     {
77       assert(volume == constgen->size<loco::DataType::S32>());
78
79       auto buf = make_buffer<int32_t, LexicalLayout>(shape);
80
81       for (IndexEnumerator e{shape}; e.valid(); e.advance())
82       {
83         const auto &index = e.current();
84         uint32_t offset = ::offset_by_index(shape, index);
85         buf.at(index) = constgen->at<loco::DataType::S32>(offset);
86       }
87
88       data = locomotiv::make_data(buf);
89       break;
90     }
91     case loco::DataType::FLOAT32:
92     {
93       assert(volume == constgen->size<loco::DataType::FLOAT32>());
94
95       auto buf = make_buffer<float, LexicalLayout>(shape);
96
97       for (IndexEnumerator e{shape}; e.valid(); e.advance())
98       {
99         const auto &index = e.current();
100         uint32_t offset = ::offset_by_index(shape, index);
101         buf.at(index) = constgen->at<loco::DataType::FLOAT32>(offset);
102       }
103
104       data = locomotiv::make_data(buf);
105       break;
106     }
107     default:
108       throw std::runtime_error("NYI for this DataType");
109   }
110
111   assert(data != nullptr);
112   annot_data(constgen, std::move(data));
113   annot_domain(constgen, loco::Domain::Tensor);
114 }
115
116 } // namespace locomotiv