d3dcf9a6dfce6796a64a6cbd5ea8affb83a56795
[platform/core/ml/nnfw.git] / runtime / onert / core / src / backend / cpu_common / Tensor.cc
1 /*
2  * Copyright (c) 2018 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 "backend/cpu_common/Tensor.h"
18
19 #include "ir/DataType.h"
20 #include "backend/cpu_common/MemoryManager.h"
21
22 namespace onert
23 {
24 namespace backend
25 {
26 namespace cpu_common
27 {
28
29 Tensor::~Tensor() {}
30
31 size_t Tensor::calcOffset(const ir::Coordinates &coords) const
32 {
33   size_t rank = num_dimensions();
34   rank = rank == 0 ? 1 : rank;
35   size_t offset = 0;
36   for (size_t i = 0; i < rank; ++i)
37   {
38     offset = offset * dimension(i) + coords[i];
39   }
40   offset *= sizeOfDataType(data_type());
41   return offset;
42 }
43
44 void Tensor::setShape(const ir::Shape &new_shape) { _info.shape(new_shape); }
45
46 bool Tensor::applyShape(const ir::Shape &new_shape)
47 {
48   bool previously_dynamic = is_dynamic();
49
50   auto allocTensorMem = [&](bool overwrite = false) {
51     auto capacity = total_size();
52     auto alloc = _dynamic_mem_mgr->allocate(this, capacity);
53
54     if (overwrite)
55       overwriteBuffer(alloc);
56     else
57       setBuffer(alloc);
58   };
59
60   if (!previously_dynamic)
61   {
62     // TODO deallocate tensor->buffer()
63     // issue is that staticTensorManager might have allocate this memory
64     setShape(new_shape);
65     set_dynamic();
66     allocTensorMem(true);
67   }
68   else if (buffer() == nullptr)
69   {
70     setShape(new_shape);
71     set_dynamic();
72     allocTensorMem();
73   }
74   // when buffer was already allocated and new_shape requires different size
75   else
76   {
77     auto previous_size = total_size();
78     auto new_size = new_shape.num_elements() * ir::sizeOfDataType(data_type());
79     if (previous_size != new_size)
80     {
81       _dynamic_mem_mgr->deallocate(this);
82
83       setShape(new_shape);
84       set_dynamic();
85       allocTensorMem(true);
86     }
87     else
88     { // when buffer with same size was already allocated, shape could differ
89       setShape(new_shape);
90     }
91   }
92   return true;
93 }
94
95 } // namespace cpu_common
96 } // namespace backend
97 } // namespace onert