blob: 9249f558bdb4374cc216d7cc37e02bc974790463 [file] [log] [blame]
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +01001// Copyright (c) 2023, ARM Limited.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14#include "generate.h"
15
16#include <doctest.h>
17
18#include <array>
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010019#include <sstream>
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +010020#include <string>
21#include <vector>
22
Jeremy Johnson59b307d2023-10-04 14:17:26 +010023namespace
24{
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010025void update_json_template(std::string& str, const std::string& find, const std::string& change)
Jeremy Johnson59b307d2023-10-04 14:17:26 +010026{
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010027 // Update the 'str' by looking for instances of 'find' and replacing them with 'change'
28 auto pos = str.find(find);
Jeremy Johnson59b307d2023-10-04 14:17:26 +010029 while (pos != std::string::npos)
30 {
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010031 str.replace(pos, find.length(), change);
Jeremy Johnson59b307d2023-10-04 14:17:26 +010032 pos = str.find(find);
33 }
34}
35
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010036void check_value(bool match, uint32_t result, uint32_t expected, uint32_t idx)
37{
38 std::stringstream msg;
39 msg << "index: " << idx << " expected: " << std::hex << expected << " got: " << result;
40 if (match)
41 {
42 REQUIRE_MESSAGE(expected == result, msg.str());
43 }
44 else
45 {
46 REQUIRE_MESSAGE(expected != result, msg.str());
47 }
48}
49
Jeremy Johnson59b307d2023-10-04 14:17:26 +010050template <typename T>
51void check_output(const std::vector<T>& results, const std::vector<uint32_t>& expected)
52{
53 for (size_t idx = 0; idx < expected.size(); ++idx)
54 {
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010055 check_value(true, *(uint32_t*)&results[idx], expected[idx], idx);
Jeremy Johnson59b307d2023-10-04 14:17:26 +010056 }
57}
58
Jeremy Johnsond41feb72023-10-12 16:03:15 +010059template <typename T>
60void check_output(const std::vector<T>& results, const std::vector<T>& expected)
61{
62 for (size_t idx = 0; idx < expected.size(); ++idx)
63 {
64 check_value(true, *(uint32_t*)&results[idx], *(uint32_t*)&expected[idx], idx);
65 }
66}
67
68template <typename T>
69void check_not_output(const std::vector<T>& results, const std::vector<T>& expected)
70{
71 for (size_t idx = 0; idx < expected.size(); ++idx)
72 {
73 check_value(false, *(uint32_t*)&results[idx], *(uint32_t*)&expected[idx], idx);
74 }
75}
76
Jeremy Johnson59b307d2023-10-04 14:17:26 +010077} // namespace
78
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +010079TEST_SUITE_BEGIN("generate");
80
81TEST_CASE("negative - api")
82{
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010083 std::string templateJsonCfg = R"({
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +010084 "tensors" : {
85 "in1" : {
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010086 "generator": "_GENERATOR_",
87 "data_type": "_TYPE_",
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +010088 "input_type": "VARIABLE",
89 "shape" : [ 4, 8, 8 ],
90 "input_pos": 0,
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010091 "op" : "_OP_",
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +010092 "dot_product_info": {
93 "s": 0,
Jeremy Johnson59b307d2023-10-04 14:17:26 +010094 "ks": 8,
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +010095 "acc_type": "_TYPE_"
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +010096 }
97 }
98 }
99 })";
100
101 const std::string tosaName = "in1";
102 const size_t tosaElements = 4 * 8 * 8;
103 const size_t tosaSize = tosaElements * 4;
104
105 SUBCASE("missing input")
106 {
107 REQUIRE_FALSE(tgd_generate_data(NULL, NULL, NULL, 0));
108 }
109 SUBCASE("invalid json")
110 {
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100111 std::string invalidJsonCfg = R"({
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100112 "tensors" : {
113 "in1" : {
114 "generator": DOT_PRODUCT,
115 },
116 }
117 })";
118
119 std::vector<float> buffer(tosaElements);
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100120 REQUIRE_FALSE(tgd_generate_data(invalidJsonCfg.c_str(), tosaName.c_str(), (void*)buffer.data(), tosaSize));
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100121 }
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100122 SUBCASE("unknown generator")
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100123 {
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100124 std::string jsonCfg = templateJsonCfg;
125 update_json_template(jsonCfg, "_GENERATOR_", "SOLAR");
126 update_json_template(jsonCfg, "_TYPE_", "FP32");
127 update_json_template(jsonCfg, "_OP_", "MATMUL");
128 std::vector<float> buffer(tosaElements);
129 REQUIRE_FALSE(tgd_generate_data(jsonCfg.c_str(), tosaName.c_str(), (void*)buffer.data(), tosaSize));
130 }
131 SUBCASE("unknown op")
132 {
133 std::string jsonCfg = templateJsonCfg;
134 update_json_template(jsonCfg, "_GENERATOR_", "DOT_PRODUCT");
135 update_json_template(jsonCfg, "_TYPE_", "FP32");
136 update_json_template(jsonCfg, "_OP_", "GREEN");
137
138 std::vector<float> buffer(tosaElements);
139 REQUIRE_FALSE(tgd_generate_data(jsonCfg.c_str(), tosaName.c_str(), (void*)buffer.data(), tosaSize));
140 }
141 SUBCASE("unknown type")
142 {
143 std::string jsonCfg = templateJsonCfg;
144 update_json_template(jsonCfg, "_GENERATOR_", "DOT_PRODUCT");
145 update_json_template(jsonCfg, "_TYPE_", "WATT");
146 update_json_template(jsonCfg, "_OP_", "MATMUL");
147
148 std::vector<float> buffer(tosaElements);
149 REQUIRE_FALSE(tgd_generate_data(jsonCfg.c_str(), tosaName.c_str(), (void*)buffer.data(), tosaSize));
150 }
151 SUBCASE("mismatching name")
152 {
153 std::string jsonCfg = templateJsonCfg;
154 update_json_template(jsonCfg, "_GENERATOR_", "DOT_PRODUCT");
155 update_json_template(jsonCfg, "_TYPE_", "FP32");
156 update_json_template(jsonCfg, "_OP_", "MATMUL");
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100157 std::string invalidName = "notFound1";
158
159 std::vector<float> buffer(tosaElements);
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100160 REQUIRE_FALSE(tgd_generate_data(jsonCfg.c_str(), invalidName.c_str(), (void*)buffer.data(), tosaSize));
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100161 }
162 SUBCASE("mismatching size")
163 {
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100164 std::string jsonCfg = templateJsonCfg;
165 update_json_template(jsonCfg, "_GENERATOR_", "DOT_PRODUCT");
166 update_json_template(jsonCfg, "_TYPE_", "FP32");
167 update_json_template(jsonCfg, "_OP_", "MATMUL");
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100168 size_t smallElements = 4 * 8 * 7;
169 size_t smallSize = smallElements * 4;
170
171 std::vector<float> buffer(smallElements);
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100172 REQUIRE_FALSE(tgd_generate_data(jsonCfg.c_str(), tosaName.c_str(), (void*)buffer.data(), smallSize));
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100173 }
174}
175
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100176void matmul_test_FP32(const std::string tosaName[2],
177 const size_t tosaElements[2],
178 const std::string templateJsonCfg,
179 const std::string setStr,
180 int32_t param,
181 const std::vector<uint32_t> expected)
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100182{
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100183 std::string jsonCfg = templateJsonCfg;
184 update_json_template(jsonCfg, "_SET_", setStr);
185 std::vector<float> buffer(tosaElements[param]);
186 REQUIRE(tgd_generate_data(jsonCfg.c_str(), tosaName[param].c_str(), (void*)buffer.data(), tosaElements[param] * 4));
187 check_output<float>(buffer, expected);
188}
189
190TEST_CASE("positive - FP32 matmul dot product (first 3 values)")
191{
192 std::string templateJsonCfg = R"({
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100193 "tensors" : {
194 "in1" : {
195 "generator": "DOT_PRODUCT",
196 "data_type": "FP32",
197 "input_type": "VARIABLE",
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100198 "shape" : [ 4, 8, 2 ],
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100199 "input_pos": 0,
200 "op" : "MATMUL",
201 "dot_product_info": {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100202 "s": _SET_,
203 "ks": 2,
204 "acc_type": "FP32"
205 }
206 },
207 "in2" : {
208 "generator": "DOT_PRODUCT",
209 "data_type": "FP32",
210 "input_type": "VARIABLE",
211 "shape" : [ 4, 2, 5 ],
212 "input_pos": 1,
213 "op" : "MATMUL",
214 "dot_product_info": {
215 "s": _SET_,
216 "ks": 2,
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100217 "acc_type": "FP32"
218 }
219 }
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100220
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100221 }
222 })";
223
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100224 const std::string tosaName[2] = { "in1", "in2" };
225 const size_t tosaElements[2] = { (4 * 8 * 2), (4 * 2 * 5) };
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100226
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100227 SUBCASE("matmul, set 0, param 0")
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100228 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100229 std::vector<uint32_t> expected = { 0xbf665aa4, 0xbf736bd3, 0x0 };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100230 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "0", 0, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100231 }
232 SUBCASE("matmul, set 0, param 1")
233 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100234 std::vector<uint32_t> expected = { 0x0, 0x0, 0x3f34f2dd };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100235 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "0", 1, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100236 }
237 SUBCASE("matmul, set 1, param 0")
238 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100239 std::vector<uint32_t> expected = { 0x5e97f1b0, 0x5ea6a18e, 0x5eb811af };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100240 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "1", 0, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100241 }
242 SUBCASE("matmul, set 1, param 1")
243 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100244 std::vector<uint32_t> expected = { 0x5f128bb1, 0x5ef54579, 0x5ebd65b8 };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100245 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "1", 1, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100246 }
247 SUBCASE("matmul, set 2, param 0")
248 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100249 std::vector<uint32_t> expected = { 0x3f800000, 0x3e66ed53, 0x3f800000 };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100250 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "2", 0, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100251 }
252 SUBCASE("matmul, set 2, param 1")
253 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100254 std::vector<uint32_t> expected = { 0x3f800000, 0x3f800000, 0x3f800000 };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100255 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "2", 1, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100256 }
257 SUBCASE("matmul, set 3, param 0")
258 {
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100259 // NOTE: Python test script produced 0xbf256686 - so off by 1
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100260 std::vector<uint32_t> expected = { 0x41800000, 0xbf256685, 0x41800000 };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100261 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "3", 0, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100262 }
263 SUBCASE("matmul, set 3, param 1")
264 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100265 std::vector<uint32_t> expected = { 0x41800000, 0x41800000, 0x41800000 };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100266 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "3", 1, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100267 }
268 SUBCASE("matmul, set 4, param 0")
269 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100270 std::vector<uint32_t> expected = { 0x0, 0x3f000000, 0x5f14e80c };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100271 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "4", 0, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100272 }
273 SUBCASE("matmul, set 4, param 1")
274 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100275 std::vector<uint32_t> expected = { 0x5d5d0db2, 0xdf2c82a8, 0x0 };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100276 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "4", 1, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100277 }
278 SUBCASE("matmul, set 5, param 0")
279 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100280 std::vector<uint32_t> expected = { 0x5df6c4b3, 0x5e6b4088, 0x5ed0fe71 };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100281 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "5", 0, expected);
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100282 }
283 SUBCASE("matmul, set 5, param 1")
284 {
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100285 std::vector<uint32_t> expected = { 0xde086d85, 0x5e630878, 0x5eba5c7b };
Jeremy Johnsonfc5e34e2023-10-24 14:45:12 +0100286 matmul_test_FP32(tosaName, tosaElements, templateJsonCfg, "5", 1, expected);
Jeremy Johnsonb20b0c92023-10-04 14:17:55 +0100287 }
288}
Jeremy Johnsond1a08ce2023-10-18 17:22:21 +0100289
290void conv2d_test_FP32(const std::string tosaName[3],
291 const size_t tosaElements[3],
292 const std::string templateJsonCfg,
293 const std::string setStr,
294 int32_t param,
295 const std::vector<uint32_t> lastExpected)
296{
297 std::string jsonCfg = templateJsonCfg;
298 update_json_template(jsonCfg, "_SET_", setStr);
299
300 std::vector<float> buffer(tosaElements[param]);
301 REQUIRE(tgd_generate_data(jsonCfg.c_str(), tosaName[param].c_str(), (void*)buffer.data(), tosaElements[param] * 4));
302 std::vector<float> last_three(buffer.end() - std::min<int>(3, buffer.size()), buffer.end());
303 check_output<float>(last_three, lastExpected);
304}
305
306TEST_CASE("positive - FP32 conv2d dot product (last 3 values)")
307{
308 std::string templateJsonCfg = R"({
309 "tensors" : {
310 "input" : {
311 "generator": "DOT_PRODUCT",
312 "data_type": "FP32",
313 "input_type": "VARIABLE",
314 "shape" : [ 1, 8, 2, 4 ],
315 "input_pos": 0,
316 "op" : "CONV2D",
317 "dot_product_info": {
318 "s": _SET_,
319 "ks": 16,
320 "acc_type": "FP32",
321 "kernel": [2, 2]
322 }
323 },
324 "weight" : {
325 "generator": "DOT_PRODUCT",
326 "data_type": "FP32",
327 "input_type": "CONSTANT",
328 "shape" : [ 2, 2, 2, 4 ],
329 "input_pos": 1,
330 "op" : "CONV2D",
331 "dot_product_info": {
332 "s": _SET_,
333 "ks": 16,
334 "acc_type": "FP32"
335 }
336 },
337 "bias" : {
338 "generator": "DOT_PRODUCT",
339 "data_type": "FP32",
340 "input_type": "CONSTANT",
341 "shape" : [ 2 ],
342 "input_pos": 2,
343 "op" : "CONV2D",
344 "dot_product_info": {
345 "s": _SET_,
346 "ks": 16,
347 "acc_type": "FP32"
348 }
349 }
350
351 }
352 })";
353
354 const std::string tosaName[3] = { "input", "weight", "bias" };
355 const size_t tosaElements[3] = { (1 * 8 * 2 * 4), (2 * 2 * 2 * 4), 2 };
356
357 SUBCASE("conv2d, set 0, param 0")
358 {
359 std::vector<uint32_t> lastExpected = { 0x0, 0xbf28bfda, 0xbe99cd47 };
360 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "0", 0, lastExpected);
361 }
362 SUBCASE("conv2d, set 0, param 1")
363 {
364 std::vector<uint32_t> lastExpected = { 0x0, 0x3f648dfd, 0xbd4cb21c };
365 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "0", 1, lastExpected);
366 }
367 SUBCASE("conv2d, set 0, param 2")
368 {
369 std::vector<uint32_t> lastExpected = { 0x0, 0x0 };
370 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "0", 2, lastExpected);
371 }
372 SUBCASE("conv2d, set 1, param 0")
373 {
374 std::vector<uint32_t> lastExpected = { 0x5e6f0400, 0x5e2f78e5, 0x5e62318d };
375 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "1", 0, lastExpected);
376 }
377 SUBCASE("conv2d, set 1, param 1")
378 {
379 // NOTE: Python test script produced 0x5e6960b0 - so off by 1
380 std::vector<uint32_t> lastExpected = { 0x5e6960af, 0x5e6d0ca9, 0x5e0b8561 };
381 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "1", 1, lastExpected);
382 }
383 SUBCASE("conv2d, set 1, param 2")
384 {
385 // NOTE: Python test script produced 0x7cf260d0, 0x7d355432 - so off by 1
386 std::vector<uint32_t> lastExpected = { 0x7cf260d1, 0x7d355431 };
387 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "1", 2, lastExpected);
388 }
389 SUBCASE("conv2d, set 2, param 0")
390 {
391 std::vector<uint32_t> lastExpected = { 0x3e7da8e9, 0x3df76a57, 0xbe338212 };
392 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "2", 0, lastExpected);
393 }
394 SUBCASE("conv2d, set 2, param 1")
395 {
396 std::vector<uint32_t> lastExpected = { 0x3daabbc5, 0xbe2f8909, 0xbdb806ec };
397 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "2", 1, lastExpected);
398 }
399 SUBCASE("conv2d, set 2, param 2")
400 {
401 std::vector<uint32_t> lastExpected = { 0x0, 0x0 };
402 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "2", 2, lastExpected);
403 }
404 SUBCASE("conv2d, set 3, param 0")
405 {
406 std::vector<uint32_t> lastExpected = { 0xbee77fe5, 0x402141c5, 0xbda1b2ed };
407 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "3", 0, lastExpected);
408 }
409 SUBCASE("conv2d, set 3, param 1")
410 {
411 // NOTE: Python test script produced 0xbe9947ac - so off by 1
412 std::vector<uint32_t> lastExpected = { 0x3f91e619, 0x3e9ac66b, 0xbe9947ad };
413 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "3", 1, lastExpected);
414 }
415 SUBCASE("conv2d, set 3, param 2")
416 {
417 std::vector<uint32_t> lastExpected = { 0x0, 0x0 };
418 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "3", 2, lastExpected);
419 }
420 SUBCASE("conv2d, set 4, param 0")
421 {
422 std::vector<uint32_t> lastExpected = { 0xdd7e8575, 0x0, 0xde569ff3 };
423 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "4", 0, lastExpected);
424 }
425 SUBCASE("conv2d, set 4, param 1")
426 {
427 std::vector<uint32_t> lastExpected = { 0x5e2d6921, 0x5e13a014, 0x0 };
428 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "4", 1, lastExpected);
429 }
430 SUBCASE("conv2d, set 4, param 2")
431 {
432 std::vector<uint32_t> lastExpected = { 0x0, 0x0 };
433 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "4", 2, lastExpected);
434 }
435 SUBCASE("conv2d, set 5, param 0")
436 {
437 std::vector<uint32_t> lastExpected = { 0x5e719fb9, 0x5e6b329c, 0xdd7617d4 };
438 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "5", 0, lastExpected);
439 }
440 SUBCASE("conv2d, set 5, param 1")
441 {
442 std::vector<uint32_t> lastExpected = { 0xde42f57a, 0x5dd68799, 0xde2ddfcb };
443 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "5", 1, lastExpected);
444 }
445 SUBCASE("conv2d, set 5, param 2")
446 {
447 std::vector<uint32_t> lastExpected = { 0x0, 0x0 };
448 conv2d_test_FP32(tosaName, tosaElements, templateJsonCfg, "5", 2, lastExpected);
449 }
450}
Jeremy Johnsond41feb72023-10-12 16:03:15 +0100451TEST_CASE("positive - pseudo random")
452{
453 std::string templateJsonCfg = R"({
454 "tensors" : {
455 "input0" : {
456 "generator": "PSEUDO_RANDOM",
457 "data_type": "FP32",
458 "input_type": "VARIABLE",
459 "shape" : [ 12, 3 ],
460 "input_pos": 0,
461 "op" : "PAD",
462 "pseudo_random_info": {
463 "rng_seed": _SEED0_
464 }
465 },
466 "input1" : {
467 "generator": "PSEUDO_RANDOM",
468 "data_type": "FP32",
469 "input_type": "VARIABLE",
470 "shape" : [ 1, 3 ],
471 "input_pos": 1,
472 "op" : "PAD",
473 "pseudo_random_info": {
474 "rng_seed": _SEED1_
475 }
476 }
477
478 }
479 })";
480
481 const std::string tosaNameP0 = "input0";
482 const size_t tosaElementsP0 = 12 * 3;
483 const std::string tosaNameP1 = "input1";
484 const size_t tosaElementsP1 = 1 * 3;
485
486 SUBCASE("pad - same rng")
487 {
488 std::string jsonCfg = templateJsonCfg;
489 update_json_template(jsonCfg, "_SEED0_", "0");
490 update_json_template(jsonCfg, "_SEED1_", "0");
491
492 std::vector<float> bufferP0(tosaElementsP0);
493 std::vector<float> bufferP1(tosaElementsP1);
494 REQUIRE(tgd_generate_data(jsonCfg.c_str(), tosaNameP0.c_str(), (void*)bufferP0.data(), tosaElementsP0 * 4));
495 REQUIRE(tgd_generate_data(jsonCfg.c_str(), tosaNameP1.c_str(), (void*)bufferP1.data(), tosaElementsP1 * 4));
496 check_output<float>(bufferP0, bufferP1);
497 }
498
499 SUBCASE("pad - different rng")
500 {
501 std::string jsonCfg = templateJsonCfg;
502 update_json_template(jsonCfg, "_SEED0_", "0");
503 update_json_template(jsonCfg, "_SEED1_", "1000");
504
505 std::vector<float> bufferP0(tosaElementsP0);
506 std::vector<float> bufferP1(tosaElementsP1);
507 REQUIRE(tgd_generate_data(jsonCfg.c_str(), tosaNameP0.c_str(), (void*)bufferP0.data(), tosaElementsP0 * 4));
508 REQUIRE(tgd_generate_data(jsonCfg.c_str(), tosaNameP1.c_str(), (void*)bufferP1.data(), tosaElementsP1 * 4));
509 check_not_output<float>(bufferP0, bufferP1);
510 }
511}
Jeremy Johnsonaee62af2023-11-02 17:16:25 +0000512
Jeremy Johnsonbfc53032023-11-01 11:29:56 +0000513void reduce_sum_test_FP32(const std::string tosaName,
514 const size_t tosaElements,
515 const std::string templateJsonCfg,
516 const std::string setStr,
517 const std::vector<uint32_t> expected)
518{
519 std::string jsonCfg = templateJsonCfg;
520 update_json_template(jsonCfg, "_SET_", setStr);
521
522 std::vector<float> buffer(tosaElements);
523 REQUIRE(tgd_generate_data(jsonCfg.c_str(), tosaName.c_str(), (void*)buffer.data(), tosaElements * 4));
524 // Choose different generator values to test at positions 6, 7 & 8
525 std::vector<float> mid_three(buffer.begin() + 6, buffer.begin() + 9);
526 check_output<float>(mid_three, expected);
527}
528
529TEST_CASE("positive - FP32 reduce_sum dot product (values 6,7 & 8)")
530{
531 std::string templateJsonCfg = R"({
532 "tensors" : {
533 "input" : {
534 "generator": "DOT_PRODUCT",
535 "data_type": "FP32",
536 "input_type": "VARIABLE",
537 "shape" : [ 5, 3, 7 ],
538 "input_pos": 0,
539 "op" : "REDUCE_SUM",
540 "dot_product_info": {
541 "s": _SET_,
542 "ks": 3,
543 "acc_type": "FP32",
544 "axis": 1
545 }
546 }
547 }
548 })";
549
550 const std::string tosaName = "input";
551 const size_t tosaElements = 5 * 3 * 7;
552
553 SUBCASE("reduce_sum, set 0, param 0")
554 {
555 std::vector<uint32_t> expected = { 0x3df2e612, 0x3f59255f, 0x0 };
556 reduce_sum_test_FP32(tosaName, tosaElements, templateJsonCfg, "0", expected);
557 }
558 SUBCASE("reduce_sum, set 1, param 0")
559 {
560 std::vector<uint32_t> expected = { 0x5edaa175, 0x5edb84c1, 0x5ea3c765 };
561 reduce_sum_test_FP32(tosaName, tosaElements, templateJsonCfg, "1", expected);
562 }
563 SUBCASE("reduce_sum, set 2, param 0")
564 {
565 std::vector<uint32_t> expected = { 0x3f800000, 0x3e73f143, 0x3f12cef8 };
566 reduce_sum_test_FP32(tosaName, tosaElements, templateJsonCfg, "2", expected);
567 }
568 SUBCASE("reduce_sum, set 3, param 0")
569 {
570 std::vector<uint32_t> expected = { 0x41800000, 0xbe9f659e, 0xbfaca78c };
571 reduce_sum_test_FP32(tosaName, tosaElements, templateJsonCfg, "3", expected);
572 }
573 SUBCASE("reduce_sum, set 4, param 0")
574 {
575 std::vector<uint32_t> expected = { 0x5e1e6f12, 0x3f000000, 0x3f000000 };
576 reduce_sum_test_FP32(tosaName, tosaElements, templateJsonCfg, "4", expected);
577 }
578 SUBCASE("reduce_sum, set 5, param 0")
579 {
580 std::vector<uint32_t> expected = { 0x5d2790c5, 0xdec3dadc, 0xdea1486e };
581 reduce_sum_test_FP32(tosaName, tosaElements, templateJsonCfg, "5", expected);
582 }
583}
Jeremy Johnsonaee62af2023-11-02 17:16:25 +0000584
585void fully_connected_test_FP32(const std::string tosaName[3],
586 const size_t tosaElements[3],
587 const std::string templateJsonCfg,
588 const std::string setStr,
589 int32_t param,
590 const std::vector<uint32_t> lastExpected)
591{
592 std::string jsonCfg = templateJsonCfg;
593 update_json_template(jsonCfg, "_SET_", setStr);
594
595 std::vector<float> buffer(tosaElements[param]);
596 REQUIRE(tgd_generate_data(jsonCfg.c_str(), tosaName[param].c_str(), (void*)buffer.data(), tosaElements[param] * 4));
597 if (param != 2)
598 {
599 // Get values at positions -8, -7 and -6 from the end
600 std::vector<float> last_three_ish(buffer.end() - 8, buffer.end() - 5);
601 check_output<float>(last_three_ish, lastExpected);
602 }
603 else
604 {
605 // Use last three as this buffer is too small
606 std::vector<float> last_three(buffer.end() - std::min<int>(3, buffer.size()), buffer.end());
607 check_output<float>(last_three, lastExpected);
608 }
609}
610TEST_CASE("positive - FP32 fully_connected dot product (values -8, -7 & -6 from the end)")
611{
612 std::string templateJsonCfg = R"({
613 "tensors" : {
614 "input" : {
615 "generator": "DOT_PRODUCT",
616 "data_type": "FP32",
617 "input_type": "VARIABLE",
618 "shape" : [ 6, 9 ],
619 "input_pos": 0,
620 "op" : "FULLY_CONNECTED",
621 "dot_product_info": {
622 "s": _SET_,
623 "ks": 9,
624 "acc_type": "FP32"
625 }
626 },
627 "weight" : {
628 "generator": "DOT_PRODUCT",
629 "data_type": "FP32",
630 "input_type": "CONSTANT",
631 "shape" : [ 4, 9 ],
632 "input_pos": 1,
633 "op" : "FULLY_CONNECTED",
634 "dot_product_info": {
635 "s": _SET_,
636 "ks": 9,
637 "acc_type": "FP32"
638 }
639 },
640 "bias" : {
641 "generator": "DOT_PRODUCT",
642 "data_type": "FP32",
643 "input_type": "CONSTANT",
644 "shape" : [ 4 ],
645 "input_pos": 2,
646 "op" : "FULLY_CONNECTED",
647 "dot_product_info": {
648 "s": _SET_,
649 "ks": 9,
650 "acc_type": "FP32"
651 }
652 }
653
654 }
655 })";
656
657 const std::string tosaName[3] = { "input", "weight", "bias" };
658 const size_t tosaElements[3] = { (6 * 9), (4 * 9), 4 };
659
660 SUBCASE("fully_connected, set 0, param 0")
661 {
662 std::vector<uint32_t> lastExpected = { 0x3f13876f, 0x0, 0x0 };
663 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "0", 0, lastExpected);
664 }
665 SUBCASE("fully_connected, set 0, param 1")
666 {
667 std::vector<uint32_t> lastExpected = { 0x0, 0x0, 0x3f648dfd };
668 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "0", 1, lastExpected);
669 }
670 SUBCASE("fully_connected, set 0, param 2")
671 {
672 std::vector<uint32_t> lastExpected = { 0x0, 0x0, 0x0 };
673 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "0", 2, lastExpected);
674 }
675 SUBCASE("fully_connected, set 1, param 0")
676 {
677 // NOTE: Python test script produced 0x5e6cc8d7 - so off by 1
678 std::vector<uint32_t> lastExpected = { 0x5e531bbf, 0x5e6cc8d8, 0x5e4e2539 };
679 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "1", 0, lastExpected);
680 }
681 SUBCASE("fully_connected, set 1, param 1")
682 {
683 std::vector<uint32_t> lastExpected = { 0x5e9870df, 0x5e9824c5, 0x5e9a898f };
684 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "1", 1, lastExpected);
685 }
686 SUBCASE("fully_connected, set 1, param 2")
687 {
688 // NOTE: Python test script produced 0x7dc95352 - so off by 1
689 std::vector<uint32_t> lastExpected = { 0x7d9a212a, 0x7dc95351, 0x7db7c1f2 };
690 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "1", 2, lastExpected);
691 }
692 SUBCASE("fully_connected, set 2, param 0")
693 {
694 std::vector<uint32_t> lastExpected = { 0xbcc1e987, 0xbe68efd7, 0x3db90130 };
695 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "2", 0, lastExpected);
696 }
697 SUBCASE("fully_connected, set 2, param 1")
698 {
699 std::vector<uint32_t> lastExpected = { 0x3e069935, 0x3de3a507, 0xbe6a0c0c };
700 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "2", 1, lastExpected);
701 }
702 SUBCASE("fully_connected, set 2, param 2")
703 {
704 std::vector<uint32_t> lastExpected = { 0x0, 0x0, 0x0 };
705 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "2", 2, lastExpected);
706 }
707 SUBCASE("fully_connected, set 3, param 0")
708 {
709 std::vector<uint32_t> lastExpected = { 0x3e57454e, 0x3b48e294, 0x3e889ece };
710 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "3", 0, lastExpected);
711 }
712 SUBCASE("fully_connected, set 3, param 1")
713 {
714 std::vector<uint32_t> lastExpected = { 0xbd20e608, 0x3f91e619, 0x3e9ac66b };
715 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "3", 1, lastExpected);
716 }
717 SUBCASE("fully_connected, set 3, param 2")
718 {
719 std::vector<uint32_t> lastExpected = { 0x0, 0x0, 0x0 };
720 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "3", 2, lastExpected);
721 }
722 SUBCASE("fully_connected, set 4, param 0")
723 {
724 std::vector<uint32_t> lastExpected = { 0x0, 0x5e29ad6d, 0x5e959eac };
725 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "4", 0, lastExpected);
726 }
727 SUBCASE("fully_connected, set 4, param 1")
728 {
729 std::vector<uint32_t> lastExpected = { 0x0, 0x5e6736d7, 0x5e44d571 };
730 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "4", 1, lastExpected);
731 }
732 SUBCASE("fully_connected, set 4, param 2")
733 {
734 std::vector<uint32_t> lastExpected = { 0x0, 0x0, 0x0 };
735 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "4", 2, lastExpected);
736 }
737 SUBCASE("fully_connected, set 5, param 0")
738 {
739 std::vector<uint32_t> lastExpected = { 0xde8b0d70, 0xdd51465a, 0x5e57c772 };
740 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "5", 0, lastExpected);
741 }
742 SUBCASE("fully_connected, set 5, param 1")
743 {
744 std::vector<uint32_t> lastExpected = { 0xddde72f1, 0xde7e31ff, 0x5e0bdb32 };
745 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "5", 1, lastExpected);
746 }
747 SUBCASE("fully_connected, set 5, param 2")
748 {
749 std::vector<uint32_t> lastExpected = { 0x0, 0x0, 0x0 };
750 fully_connected_test_FP32(tosaName, tosaElements, templateJsonCfg, "5", 2, lastExpected);
751 }
752}
Jeremy Johnson59b307d2023-10-04 14:17:26 +0100753TEST_SUITE_END(); // generate