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