blob: 3f69ef36c55bc601781e7511009a11fc332b55b5 [file] [log] [blame]
Chao Mei6ddfc602020-05-13 22:29:36 -07001// Copyright 2020 Google LLC
2//
3// This source code is licensed under the BSD-style license found in the
4// LICENSE file in the root directory of this source tree.
5
6#include <xnnpack.h>
7#include <xnnpack/memory-planner.h>
8#include <xnnpack/subgraph.h>
9
10#include <gtest/gtest.h>
11
12TEST(MemoryPlanner, ValueLiveInfo) {
13 EXPECT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
14 // Create simple subgraph where it has 2 nodes and 4 tensors as illustrated below:
15 // T0 ----> N0 ----> T2 and T2 ----> N1 ----> T3
16 // T1 ----/ T1 ----/
17 struct xnn_subgraph subgraph;
18 subgraph.num_values = 4;
19 subgraph.num_nodes = 2;
20 struct xnn_node nodes[2];
21 nodes[0].num_inputs = 2;
22 nodes[0].inputs[0] = 0;
23 nodes[0].inputs[1] = 1;
24 nodes[0].num_outputs = 1;
25 nodes[0].outputs[0] = 2;
26
27 nodes[1].num_inputs = 2;
28 nodes[1].inputs[0] = 1;
29 nodes[1].inputs[1] = 2;
30 nodes[1].num_outputs = 1;
31 nodes[1].outputs[0] = 3;
32 subgraph.nodes = nodes;
33
34 struct xnn_value_allocation_tracker tracker;
35 xnn_init_value_allocation_tracker(&tracker, &subgraph);
36
37 EXPECT_EQ(0, tracker.usage[0].first_node);
38 EXPECT_EQ(0, tracker.usage[0].last_node);
39
40 EXPECT_EQ(0, tracker.usage[1].first_node);
41 EXPECT_EQ(1, tracker.usage[1].last_node);
42
43 EXPECT_EQ(0, tracker.usage[2].first_node);
44 EXPECT_EQ(1, tracker.usage[2].last_node);
45
46 EXPECT_EQ(1, tracker.usage[3].first_node);
47 EXPECT_EQ(1, tracker.usage[3].last_node);
48
49 xnn_release_value_allocation_tracker(&tracker);
50}
51
52TEST(MemoryPlanner, MemoryBlocksCoalescing) {
53 EXPECT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
54 struct xnn_subgraph subgraph;
55 subgraph.num_nodes = 0;
56 subgraph.num_values = 5;
57 struct xnn_value_allocation_tracker tracker;
58 xnn_init_value_allocation_tracker(&tracker, &subgraph);
59 // As this is an empty subgraph, we create the following xnn_value_usage stub.
60 tracker.usage[0] = (struct xnn_value_usage){
61 .first_node = 1,
62 .last_node = 1,
63 };
64 xnn_add_value_allocation_tracker(&tracker, 0, 56);
65
66 tracker.usage[1] = (struct xnn_value_usage){
67 .first_node = 0,
68 .last_node = 1,
69 };
70 xnn_add_value_allocation_tracker(&tracker, 1, 40);
71
72 tracker.usage[2] = (struct xnn_value_usage){
73 .first_node = 1,
74 .last_node = 1,
75 };
76 xnn_add_value_allocation_tracker(&tracker, 2, 64);
77
78 tracker.usage[3] = (struct xnn_value_usage){
79 .first_node = 0,
80 .last_node = 0,
81 };
82 xnn_add_value_allocation_tracker(&tracker, 3, 152);
83
84 tracker.usage[4] = (struct xnn_value_usage){
85 .first_node = 1,
86 .last_node = 1,
87 };
88 xnn_add_value_allocation_tracker(&tracker, 4, 20);
89
90 xnn_plan_value_allocation_tracker(&tracker);
91
92#if XNN_ENABLE_MEMOPT
93 EXPECT_EQ(192, tracker.mem_arena_size);
94 EXPECT_EQ(64, tracker.usage[0].alloc_offset);
95 EXPECT_EQ(152, tracker.usage[1].alloc_offset);
96 EXPECT_EQ(0, tracker.usage[2].alloc_offset);
97 EXPECT_EQ(0, tracker.usage[3].alloc_offset);
98 EXPECT_EQ(120, tracker.usage[4].alloc_offset);
99#else
100 EXPECT_EQ(332, tracker.mem_arena_size);
101 EXPECT_EQ(0, tracker.usage[0].alloc_offset);
102 EXPECT_EQ(57, tracker.usage[1].alloc_offset);
103 EXPECT_EQ(96, tracker.usage[2].alloc_offset);
104 EXPECT_EQ(160, tracker.usage[3].alloc_offset);
105 EXPECT_EQ(312, tracker.usage[4].alloc_offset);
106#endif
107
108 xnn_release_value_allocation_tracker(&tracker);
109}
110
111TEST(MemoryPlanner, GeneralPlanning) {
112 EXPECT_EQ(xnn_status_success, xnn_initialize(nullptr /* allocator */));
113 struct xnn_subgraph subgraph;
114 subgraph.num_nodes = 0;
115 subgraph.num_values = 8;
116 struct xnn_value_allocation_tracker tracker;
117 xnn_init_value_allocation_tracker(&tracker, &subgraph);
118 // As this is an empty subgraph, we create the following xnn_value_usage stub.
119 tracker.usage[0] = (struct xnn_value_usage){
120 .first_node = 0,
121 .last_node = 1,
122 };
123 xnn_add_value_allocation_tracker(&tracker, 0, 32);
124
125 tracker.usage[1] = (struct xnn_value_usage){
126 .first_node = 1,
127 .last_node = 4,
128 };
129 xnn_add_value_allocation_tracker(&tracker, 1, 28);
130
131 tracker.usage[2] = (struct xnn_value_usage){
132 .first_node = 2,
133 .last_node = 5,
134 };
135 xnn_add_value_allocation_tracker(&tracker, 2, 36);
136
137 tracker.usage[3] = (struct xnn_value_usage){
138 .first_node = 3,
139 .last_node = 5,
140 };
141 xnn_add_value_allocation_tracker(&tracker, 3, 16);
142
143 tracker.usage[4] = (struct xnn_value_usage){
144 .first_node = 4,
145 .last_node = 5,
146 };
147 xnn_add_value_allocation_tracker(&tracker, 4, 8);
148
149 tracker.usage[5] = (struct xnn_value_usage){
150 .first_node = 5,
151 .last_node = 7,
152 };
153 xnn_add_value_allocation_tracker(&tracker, 5, 64);
154
155 tracker.usage[6] = (struct xnn_value_usage){
156 .first_node = 6,
157 .last_node = 8,
158 };
159 xnn_add_value_allocation_tracker(&tracker, 6, 10);
160
161 tracker.usage[7] = (struct xnn_value_usage){
162 .first_node = 7,
163 .last_node = 8,
164 };
165 xnn_add_value_allocation_tracker(&tracker, 7, 40);
166
167 xnn_plan_value_allocation_tracker(&tracker);
168
169#if XNN_ENABLE_MEMOPT
170 EXPECT_EQ(124, tracker.mem_arena_size);
171 EXPECT_EQ(0, tracker.usage[0].alloc_offset);
172 EXPECT_EQ(32, tracker.usage[1].alloc_offset);
173 EXPECT_EQ(64, tracker.usage[2].alloc_offset);
174 EXPECT_EQ(100, tracker.usage[3].alloc_offset);
175 EXPECT_EQ(116, tracker.usage[4].alloc_offset);
176 EXPECT_EQ(0, tracker.usage[5].alloc_offset);
177 EXPECT_EQ(104, tracker.usage[6].alloc_offset);
178 EXPECT_EQ(64, tracker.usage[7].alloc_offset);
179#else
180 EXPECT_EQ(234, tracker.mem_arena_size);
181 EXPECT_EQ(0, tracker.usage[0].alloc_offset);
182 EXPECT_EQ(32, tracker.usage[1].alloc_offset);
183 EXPECT_EQ(60, tracker.usage[2].alloc_offset);
184 EXPECT_EQ(96, tracker.usage[3].alloc_offset);
185 EXPECT_EQ(112, tracker.usage[4].alloc_offset);
186 EXPECT_EQ(120, tracker.usage[5].alloc_offset);
187 EXPECT_EQ(184, tracker.usage[6].alloc_offset);
188 EXPECT_EQ(194, tracker.usage[7].alloc_offset);
189#endif
190
191 xnn_release_value_allocation_tracker(&tracker);
192}