summaryrefslogtreecommitdiff
path: root/runtimes/neurun/backend/cpu/MemoryPlanner.cc
blob: 8eaf7bb9ed2b2169c9735be3bf8912c7f27685ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "MemoryPlanner.h"
#include "util/logging.h"
#include <cassert>

namespace neurun
{
namespace backend
{
namespace cpu
{

Allocator::Allocator(uint32_t capacity)
{
  _base = nnfw::cpp14::make_unique<uint8_t[]>(capacity);

  VERBOSE(ALLOC) << "allocation capacity: " << capacity << std::endl;
  VERBOSE(ALLOC) << "base pointer: " << static_cast<void *>(_base.get()) << std::endl;
}

void BumpPlanner::claim(const model::OperandIndex &ind, size_t size)
{
  assert(size != 0);

  Block blk{_capacity, size};
  _mem_plans[ind] = blk;
  _capacity += size;

  VERBOSE(BP_PLANNER) << "CLAIM(#" << ind.value() << "): " << blk.offset << ", " << blk.size
                      << std::endl;
}

void BumpPlanner::release(const model::OperandIndex &ind)
{
  VERBOSE(BP_PLANNER) << "RELEASE(#" << ind.value() << "): "
                      << "NOTHING does" << std::endl;
}

// There are some assumptions for claiming memory(== making a reservation for memory).
// 1. About _claim_table(std::map).
//   - The table's data structure is std::map so that it always sorts
//     value(model::OperandIndex) by key(base_offset).
//   - This claim() inserts key/value into _claim_table and the release() removes the key/value from
//     _claim_table.
//   - _claim_table shows the memory status at a certain point in time. Therefore,
//     - If _claim_table has an offset and a certain size at a certain point in time,
//       it means the place at the offset has been already claimed(== can't claim now. need to find
//       someplace new).
//     - If _claim_table doesn't have any element for an offset and a certain size at a certain
//       point in time, it means the place at the offset can be claimed.
// 2. In the loop for _claim_table, we can assume the current claim_base_offset value is bigger than
//    the previous claim_base_offset.
void FirstFitPlanner::claim(const model::OperandIndex &ind, size_t size)
{
  assert(size != 0);

  // Find the right position for claiming
  uint32_t next_offset = 0;
  for (auto &mem_claim : _claim_table)
  {
    auto claimed_base_offset = mem_claim.first;
    auto claimed_size = _mem_plans[mem_claim.second].size;
    if (next_offset + size <= claimed_base_offset)
    {
      break;
    }
    else
    {
      next_offset = claimed_base_offset + claimed_size;
    }
  }

  // Now next_offset is set to the proper offset
  _claim_table[next_offset] = ind;
  _mem_plans[ind] = {next_offset, size};

  VERBOSE(FF_PLANNER) << "claim(#" << ind.value() << "): [+" << next_offset << ", " << size << "sz]"
                      << std::endl;

  if (_capacity < next_offset + size)
  {
    _capacity = next_offset + size;
  }
}

void FirstFitPlanner::release(const model::OperandIndex &ind)
{
  for (auto it = _claim_table.cbegin(); it != _claim_table.cend(); ++it)
  {
    if (it->second == ind)
    {
      uint32_t offset = it->first;
      uint32_t index = ind.value();
      uint32_t size = _mem_plans[ind].size;

      _claim_table.erase(it);

      VERBOSE(FF_PLANNER) << "release(#" << index << "): [+" << offset << ", " << size << "sz]"
                          << std::endl;
      return;
    }
  }
  assert(!"Cannot release for given index. It has been not claimed or released already.");
}

} // namespace cpu
} // namespace backend
} // namespace neurun