Skip to content

Commit dbd44d4

Browse files
adstrawylc
authored andcommitted
Add unit tests for HexagonBuffer (apache#9736)
* Add unit tests for HexagonBuffer * fix build error for signed / unsigned comparison
1 parent 76cbc6f commit dbd44d4

File tree

4 files changed

+256
-1
lines changed

4 files changed

+256
-1
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ endif()
632632
if(GTEST_FOUND)
633633
file(GLOB_RECURSE TEST_SRCS tests/cpp/*.cc)
634634
add_executable(cpptest ${TEST_SRCS})
635+
# include runtime files for unit testing
636+
target_include_directories(cpptest PUBLIC "src/runtime")
635637
target_link_libraries(cpptest PRIVATE ${TVM_TEST_LIBRARY_NAME} GTest::GTest GTest::Main pthread dl)
636638
set_target_properties(cpptest PROPERTIES EXCLUDE_FROM_ALL 1)
637639
set_target_properties(cpptest PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1)

cmake/modules/Hexagon.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ if (NOT BUILD_FOR_HEXAGON AND NOT BUILD_FOR_ANDROID)
7575
USE_HEXAGON_PROXY_RPC STREQUAL "OFF" AND NOT USE_HEXAGON_RPC)
7676
if(USE_HEXAGON_DEVICE STREQUAL "OFF")
7777
list(APPEND COMPILER_SRCS src/target/opt/build_hexagon_off.cc)
78+
# append select runtime sources for unit testing
79+
list(APPEND RUNTIME_SRCS src/runtime/hexagon/hexagon/hexagon_buffer.cc)
80+
list(APPEND RUNTIME_SRCS src/runtime/hexagon/hexagon/hexagon_common.cc)
7881
if (NOT USE_HEXAGON_RPC)
7982
return()
8083
endif()

src/runtime/hexagon/hexagon/hexagon_common.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ PackedFunc WrapPackedFunc(TVMBackendPackedCFunc faddr, const ObjectPtr<Object>&
8383

8484
TVMValue* arg_values = const_cast<TVMValue*>(args.values);
8585
std::vector<std::pair<size_t, HexagonBuffer*>> buffer_args;
86-
for (size_t i = 0; i < args.num_args; i++) {
86+
for (int i = 0; i < args.num_args; i++) {
8787
if (args.type_codes[i] == kTVMDLTensorHandle) {
8888
DLTensor* tensor = static_cast<DLTensor*>(arg_values[i].v_handle);
8989
buffer_args.emplace_back(i, static_cast<HexagonBuffer*>(tensor->data));
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include <gtest/gtest.h>
21+
#include <hexagon/hexagon/hexagon_buffer.h>
22+
#include <tvm/runtime/container/optional.h>
23+
24+
using namespace tvm::runtime;
25+
using namespace tvm::runtime::hexagon;
26+
27+
TEST(HexagonBuffer, default_scope) {
28+
Optional<String> scope;
29+
HexagonBuffer hb(8 /* nbytes */, 8 /* alignment */, scope);
30+
EXPECT_EQ(hb.GetStorageScope(), HexagonBuffer::StorageScope::kDDR);
31+
}
32+
33+
TEST(HexagonBuffer, ddr_scope) {
34+
Optional<String> scope("global");
35+
HexagonBuffer hb(8 /* nbytes */, 8 /* alignment */, scope);
36+
EXPECT_EQ(hb.GetStorageScope(), HexagonBuffer::StorageScope::kDDR);
37+
}
38+
39+
TEST(HexagonBuffer, vtcm_scope) {
40+
Optional<String> scope("global.vtcm");
41+
HexagonBuffer hb(8 /* nbytes */, 8 /* alignment */, scope);
42+
EXPECT_EQ(hb.GetStorageScope(), HexagonBuffer::StorageScope::kVTCM);
43+
}
44+
45+
TEST(HexagonBuffer, invalid_scope) {
46+
Optional<String> scope("invalid");
47+
EXPECT_THROW(HexagonBuffer hb(8 /* nbytes */, 8 /* alignment */, scope), InternalError);
48+
}
49+
50+
TEST(HexagonBuffer, copy_from) {
51+
Optional<String> scope("global");
52+
HexagonBuffer hb(8 /* nbytes */, 8 /* alignment */, scope);
53+
54+
std::vector<uint8_t> data{0, 1, 2, 3, 4, 5, 6, 7};
55+
hb.CopyFrom(data.data(), data.size());
56+
57+
uint8_t* ptr = static_cast<uint8_t*>(hb.GetPointer()[0]);
58+
for (size_t i = 0; i < data.size(); ++i) {
59+
EXPECT_EQ(ptr[i], data[i]);
60+
}
61+
}
62+
63+
TEST(HexagonBuffer, copy_from_invalid_size) {
64+
Optional<String> scope("global");
65+
std::vector<uint8_t> data{0, 1, 2, 3, 4, 5, 6, 7};
66+
67+
// HexagonBuffer too small
68+
HexagonBuffer toosmall(4 /* nbytes */, 8 /* alignment */, scope);
69+
EXPECT_THROW(toosmall.CopyFrom(data.data(), data.size()), InternalError);
70+
71+
// HexagonBuffer too big
72+
HexagonBuffer toobig(16 /* nbytes */, 16 /* alignment */, scope);
73+
EXPECT_THROW(toobig.CopyFrom(data.data(), data.size()), InternalError);
74+
}
75+
76+
TEST(HexagonBuffer, nd) {
77+
Optional<String> def;
78+
HexagonBuffer hb_default(2 /* ndim */, 4 /* nbytes */, 8 /* alignment */, def);
79+
EXPECT_EQ(hb_default.GetStorageScope(), HexagonBuffer::StorageScope::kDDR);
80+
81+
Optional<String> global("global");
82+
HexagonBuffer hb_global(2 /* ndim */, 4 /* nbytes */, 8 /* alignment */, global);
83+
EXPECT_EQ(hb_global.GetStorageScope(), HexagonBuffer::StorageScope::kDDR);
84+
85+
Optional<String> vtcm("global.vtcm");
86+
HexagonBuffer hb_vtcm(2 /* ndim */, 4 /* nbytes */, 8 /* alignment */, vtcm);
87+
EXPECT_EQ(hb_vtcm.GetStorageScope(), HexagonBuffer::StorageScope::kVTCM);
88+
89+
Optional<String> invalid("invalid");
90+
EXPECT_THROW(HexagonBuffer hb_invalid(2 /* ndim */, 4 /* nbytes */, 8 /* alignment */, invalid),
91+
InternalError);
92+
}
93+
94+
TEST(HexagonBuffer, nd_copy_from) {
95+
Optional<String> scope("global");
96+
HexagonBuffer hb(2 /* ndim */, 4 /* nbytes */, 8 /* alignment */, scope);
97+
98+
std::vector<uint8_t> data{0, 1, 2, 3, 4, 5, 6, 7};
99+
hb.CopyFrom(data.data(), data.size());
100+
101+
uint8_t* ptr = static_cast<uint8_t*>(hb.GetPointer()[0]);
102+
EXPECT_EQ(ptr[0], data[0]);
103+
EXPECT_EQ(ptr[1], data[1]);
104+
EXPECT_EQ(ptr[2], data[2]);
105+
EXPECT_EQ(ptr[3], data[3]);
106+
107+
ptr = static_cast<uint8_t*>(hb.GetPointer()[1]);
108+
EXPECT_EQ(ptr[0], data[4]);
109+
EXPECT_EQ(ptr[1], data[5]);
110+
EXPECT_EQ(ptr[2], data[6]);
111+
EXPECT_EQ(ptr[3], data[7]);
112+
}
113+
114+
TEST(HexagonBuffer, 1d_copy_from_1d) {
115+
Optional<String> global("global");
116+
HexagonBuffer from(8 /* nbytes */, 8 /* alignment */, global);
117+
118+
Optional<String> vtcm("global.vtcm");
119+
HexagonBuffer to(8 /* nbytes */, 8 /* alignment */, vtcm);
120+
121+
std::vector<uint8_t> data{0, 1, 2, 3, 4, 5, 6, 7};
122+
from.CopyFrom(data.data(), data.size());
123+
to.CopyFrom(from);
124+
125+
uint8_t* ptr = static_cast<uint8_t*>(to.GetPointer()[0]);
126+
for (size_t i = 0; i < data.size(); ++i) {
127+
EXPECT_EQ(ptr[i], data[i]);
128+
}
129+
}
130+
131+
TEST(HexagonBuffer, 2d_copy_from_1d) {
132+
Optional<String> vtcm("global.vtcm");
133+
HexagonBuffer hb1d(8 /* nbytes */, 8 /* alignment */, vtcm);
134+
135+
Optional<String> global("global");
136+
HexagonBuffer hb2d(2 /* ndim */, 4 /* nbytes */, 8 /* alignment */, global);
137+
138+
std::vector<uint8_t> data{0, 1, 2, 3, 4, 5, 6, 7};
139+
hb1d.CopyFrom(data.data(), data.size());
140+
hb2d.CopyFrom(hb1d);
141+
142+
uint8_t* ptr = static_cast<uint8_t*>(hb2d.GetPointer()[0]);
143+
EXPECT_EQ(ptr[0], data[0]);
144+
EXPECT_EQ(ptr[1], data[1]);
145+
EXPECT_EQ(ptr[2], data[2]);
146+
EXPECT_EQ(ptr[3], data[3]);
147+
148+
ptr = static_cast<uint8_t*>(hb2d.GetPointer()[1]);
149+
EXPECT_EQ(ptr[0], data[4]);
150+
EXPECT_EQ(ptr[1], data[5]);
151+
EXPECT_EQ(ptr[2], data[6]);
152+
EXPECT_EQ(ptr[3], data[7]);
153+
}
154+
155+
TEST(HexagonBuffer, 1d_copy_from_2d) {
156+
Optional<String> vtcm("global.vtcm");
157+
HexagonBuffer hb2d(2 /* ndim */, 4 /* nbytes */, 8 /* alignment */, vtcm);
158+
159+
Optional<String> global("global.vtcm");
160+
HexagonBuffer hb1d(8 /* nbytes */, 8 /* alignment */, global);
161+
162+
std::vector<uint8_t> data{0, 1, 2, 3, 4, 5, 6, 7};
163+
hb2d.CopyFrom(data.data(), data.size());
164+
hb1d.CopyFrom(hb2d);
165+
166+
uint8_t* ptr = static_cast<uint8_t*>(hb1d.GetPointer()[0]);
167+
for (size_t i = 0; i < data.size(); ++i) {
168+
EXPECT_EQ(ptr[i], data[i]);
169+
}
170+
}
171+
172+
TEST(HexagonBuffer, nd_copy_from_nd_invalid_size) {
173+
Optional<String> scope("global");
174+
HexagonBuffer hb1d(8 /* nbytes */, 8 /* alignment */, scope);
175+
HexagonBuffer hb2d(2 /* ndim */, 4 /* nbytes */, 8 /* alignment */, scope);
176+
177+
HexagonBuffer toosmall1d(4 /* nbytes */, 8 /* alignment */, scope);
178+
EXPECT_THROW(hb1d.CopyFrom(toosmall1d), InternalError);
179+
EXPECT_THROW(hb2d.CopyFrom(toosmall1d), InternalError);
180+
181+
HexagonBuffer toosbig1d(16 /* nbytes */, 16 /* alignment */, scope);
182+
EXPECT_THROW(hb1d.CopyFrom(toosbig1d), InternalError);
183+
EXPECT_THROW(hb2d.CopyFrom(toosbig1d), InternalError);
184+
185+
HexagonBuffer toosmall2d(2 /* ndim */, 2 /* nbytes */, 8 /* alignment */, scope);
186+
EXPECT_THROW(hb1d.CopyFrom(toosmall2d), InternalError);
187+
EXPECT_THROW(hb2d.CopyFrom(toosmall2d), InternalError);
188+
189+
HexagonBuffer toobig2d(2 /* ndim */, 16 /* nbytes */, 16 /* alignment */, scope);
190+
EXPECT_THROW(hb1d.CopyFrom(toobig2d), InternalError);
191+
EXPECT_THROW(hb2d.CopyFrom(toobig2d), InternalError);
192+
}
193+
194+
TEST(HexagonBuffer, md_copy_from_nd) {
195+
Optional<String> scope("global");
196+
HexagonBuffer hb3d(3 /* ndim */, 4 /* nbytes */, 8 /* alignment */, scope);
197+
HexagonBuffer hb4d(4 /* ndim */, 3 /* nbytes */, 8 /* alignment */, scope);
198+
EXPECT_THROW(hb3d.CopyFrom(hb4d), InternalError);
199+
EXPECT_THROW(hb4d.CopyFrom(hb3d), InternalError);
200+
}
201+
202+
TEST(HexagonBuffer, copy_to) {
203+
Optional<String> scope("global");
204+
HexagonBuffer hb(8 /* nbytes */, 8 /* alignment */, scope);
205+
206+
std::vector<uint8_t> data_in{0, 1, 2, 3, 4, 5, 6, 7};
207+
hb.CopyFrom(data_in.data(), data_in.size());
208+
209+
std::vector<uint8_t> data_out{7, 6, 5, 4, 3, 2, 1, 0};
210+
hb.CopyTo(data_out.data(), data_out.size());
211+
212+
for (size_t i = 0; i < data_in.size(); ++i) {
213+
EXPECT_EQ(data_in[i], data_out[i]);
214+
}
215+
}
216+
217+
TEST(HexagonBuffer, nd_copy_to) {
218+
Optional<String> scope("global");
219+
HexagonBuffer hb(2 /* ndim */, 4 /* nbytes */, 8 /* alignment */, scope);
220+
221+
std::vector<uint8_t> data_in{0, 1, 2, 3, 4, 5, 6, 7};
222+
hb.CopyFrom(data_in.data(), data_in.size());
223+
224+
std::vector<uint8_t> data_out{7, 6, 5, 4, 3, 2, 1, 0};
225+
hb.CopyTo(data_out.data(), data_out.size());
226+
227+
for (size_t i = 0; i < data_in.size(); ++i) {
228+
EXPECT_EQ(data_in[i], data_out[i]);
229+
}
230+
}
231+
232+
TEST(HexagonBuffer, external) {
233+
std::vector<uint8_t> data{0, 1, 2, 3, 4, 5, 6, 7};
234+
235+
Optional<String> def;
236+
HexagonBuffer hb_default(data.data(), data.size(), def);
237+
EXPECT_EQ(hb_default.GetPointer()[0], data.data());
238+
EXPECT_EQ(hb_default.GetStorageScope(), HexagonBuffer::StorageScope::kDDR);
239+
240+
Optional<String> global("global");
241+
HexagonBuffer hb_global(data.data(), data.size(), global);
242+
EXPECT_EQ(hb_global.GetPointer()[0], data.data());
243+
EXPECT_EQ(hb_global.GetStorageScope(), HexagonBuffer::StorageScope::kDDR);
244+
245+
Optional<String> vtcm("global.vtcm");
246+
EXPECT_THROW(HexagonBuffer hb_vtcm(data.data(), data.size(), vtcm), InternalError);
247+
248+
Optional<String> invalid("invalid");
249+
EXPECT_THROW(HexagonBuffer hb_vtcm(data.data(), data.size(), invalid), InternalError);
250+
}

0 commit comments

Comments
 (0)