aboutsummaryrefslogtreecommitdiff
path: root/reference_model/test/model_runner_tests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'reference_model/test/model_runner_tests.cpp')
-rw-r--r--reference_model/test/model_runner_tests.cpp397
1 files changed, 309 insertions, 88 deletions
diff --git a/reference_model/test/model_runner_tests.cpp b/reference_model/test/model_runner_tests.cpp
index 8304bc7..bb57657 100644
--- a/reference_model/test/model_runner_tests.cpp
+++ b/reference_model/test/model_runner_tests.cpp
@@ -17,8 +17,11 @@
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#endif
-#include "model_runner.h"
#include "general_utils.h"
+#include "model_runner.h"
+#include "operators.h"
+
+#include <numeric>
// Remove conflicting REQUIRE definition between doctest and reference_model
#undef REQUIRE
@@ -33,125 +36,343 @@ void compareOutput(std::vector<T>& tensor1, std::vector<T>& tensor2, size_t size
{
for (size_t i = 0; i < size; ++i)
{
- CHECK((tensor1[i] == tensor2[i]));
+ CHECK_MESSAGE(tensor1[i] == doctest::Approx(tensor2[i]), "");
}
}
TEST_SUITE("model_runner")
{
-TEST_CASE("simple_add_f32_test")
-{
- std::string test_root(std::string(PROJECT_ROOT) + "../examples/test_add_1x4x4x4_f32/");
- std::string tosa_model_file(test_root + "flatbuffer-tflite/test_add_1x4x4x4_f32.tosa");
- std::string input0_file(test_root + "placeholder_0.npy");
- std::string input1_file(test_root + "placeholder_1.npy");
- std::string expected_output_file(test_root + "tflite_result.npy");
+ TEST_CASE("op_entry_add")
+ {
+ // Inputs/Outputs
+ tosa_datatype_t dt = tosa_datatype_fp32_t;
+ std::vector<int32_t> input_shape = { 2, 4, 4, 1 };
+ std::vector<int32_t> output_shape = { 2, 4, 4, 1 };
+ std::vector<float> srcData1(32, 4.0f);
+ std::vector<float> srcData2(32, 3.0f);
+ std::vector<float> dstData(32, 0.0f);
+
+ tosa_tensor_t input1;
+ input1.shape = input_shape.data();
+ input1.num_dims = input_shape.size();
+ input1.data_type = dt;
+ input1.data = reinterpret_cast<uint8_t*>(srcData1.data());
+ input1.size = srcData1.size() * sizeof(float);
+
+ tosa_tensor_t input2;
+ input2.shape = input_shape.data();
+ input2.num_dims = input_shape.size();
+ input2.data_type = dt;
+ input2.data = reinterpret_cast<uint8_t*>(srcData2.data());
+ input2.size = srcData2.size() * sizeof(float);
+
+ tosa_tensor_t output;
+ output.shape = output_shape.data();
+ output.num_dims = output_shape.size();
+ output.data_type = dt;
+ output.data = reinterpret_cast<uint8_t*>(dstData.data());
+ output.size = dstData.size() * sizeof(float);
+
+ // Execution
+ auto status = tosa_run_add(input1, input2, output);
+ CHECK((status == tosa_status_valid));
+
+ // Compare results
+ std::vector<float> expectedData(8, 7.0f);
+ compareOutput(dstData, expectedData, expectedData.size());
+ }
- std::vector<std::string> input_names = { "TosaInput_0", "TosaInput_1" };
- std::string output_name = "TosaOutput_0";
+ TEST_CASE("op_entry_avg_pool2d")
+ {
+ // Pool parameters
+ const int32_t kernel[2] = { 2, 2 };
+ const int32_t stride[2] = { 2, 2 };
+ const int32_t pad[4] = { 0, 0, 0, 0 };
+
+ // Inputs/Outputs
+ tosa_datatype_t dt = tosa_datatype_fp32_t;
+ std::vector<int32_t> input_shape = { 2, 4, 4, 1 };
+ std::vector<int32_t> output_shape = { 2, 2, 2, 1 };
+ std::vector<float> srcData(32, 7.0f);
+ std::vector<float> dstData(8, 0.f);
+
+ tosa_tensor_t input;
+ input.shape = input_shape.data();
+ input.num_dims = input_shape.size();
+ input.data_type = dt;
+ input.data = reinterpret_cast<uint8_t*>(srcData.data());
+ input.size = srcData.size() * sizeof(float);
+
+ tosa_tensor_t output;
+ output.shape = output_shape.data();
+ output.num_dims = output_shape.size();
+ output.data_type = dt;
+ output.data = reinterpret_cast<uint8_t*>(dstData.data());
+ output.size = dstData.size() * sizeof(float);
+
+ // Execution
+ auto status = tosa_run_avg_pool2d(input, kernel, stride, pad, 0, 0, output);
+ CHECK((status == tosa_status_valid));
+
+ // Compare results
+ std::vector<float> expectedData(8, 7.0f);
+ compareOutput(dstData, expectedData, expectedData.size());
+ }
- std::vector<int32_t> input0_shape = { 1, 4, 4, 1 };
- std::vector<int32_t> input1_shape = { 1, 4, 4, 4 };
- std::vector<int32_t> output_shape = { 1, 4, 4, 4 };
+ TEST_CASE("op_entry_conv2d")
+ {
+ // Conv parameters
+ const int32_t stride[2] = { 1, 1 };
+ const int32_t pad[4] = { 0, 0, 0, 0 };
+ const int32_t dilation[2] = { 1, 1 };
+
+ // Inputs/Outputs
+ tosa_datatype_t dt = tosa_datatype_fp32_t;
+ std::vector<int32_t> input_shape = { 1, 32, 32, 8 };
+ std::vector<int32_t> output_shape = { 1, 32, 32, 16 };
+ std::vector<int32_t> weight_shape = { 16, 1, 1, 8 };
+ std::vector<int32_t> bias_shape = { 16 };
+ std::vector<float> srcData(32 * 32 * 8, 1.0f);
+ std::vector<float> dstData(32 * 32 * 16, 0.f);
+ std::vector<float> biasData(16, 0.f);
+ std::vector<float> weightData(16 * 8, 1.0f);
+
+ tosa_tensor_t input;
+ input.shape = input_shape.data();
+ input.num_dims = input_shape.size();
+ input.data_type = dt;
+ input.data = reinterpret_cast<uint8_t*>(srcData.data());
+ input.size = srcData.size() * sizeof(float);
+
+ tosa_tensor_t weight;
+ weight.shape = weight_shape.data();
+ weight.num_dims = weight_shape.size();
+ weight.data_type = dt;
+ weight.data = reinterpret_cast<uint8_t*>(weightData.data());
+ weight.size = weightData.size() * sizeof(float);
+
+ tosa_tensor_t bias;
+ bias.shape = bias_shape.data();
+ bias.num_dims = bias_shape.size();
+ bias.data_type = dt;
+ bias.data = reinterpret_cast<uint8_t*>(biasData.data());
+ bias.size = biasData.size() * sizeof(float);
+
+ tosa_tensor_t output;
+ output.shape = output_shape.data();
+ output.num_dims = output_shape.size();
+ output.data_type = dt;
+ output.data = reinterpret_cast<uint8_t*>(dstData.data());
+ output.size = dstData.size() * sizeof(float);
+
+ const int32_t input_zp = 0;
+ const int32_t weight_zp = 0;
+
+ // Execution
+ auto status = tosa_run_conv2d(input, weight, bias, pad, stride, dilation, input_zp, weight_zp, output);
+ CHECK((status == tosa_status_valid));
+
+ // Compare results
+ std::vector<float> expectedData(32 * 32 * 16, 8.0f);
+ compareOutput(dstData, expectedData, expectedData.size());
+ }
- std::vector<std::vector<float>> inputs(input_names.size());
- std::vector<float> actual_outputs = { };
- std::vector<float> expected_outputs = { };
+ TEST_CASE("op_entry_max_pool2d")
+ {
+ // Pool parameters
+ const int32_t kernel[2] = { 2, 2 };
+ const int32_t stride[2] = { 2, 2 };
+ const int32_t pad[4] = { 0, 0, 0, 0 };
+
+ // Inputs/Outputs
+ tosa_datatype_t dt = tosa_datatype_fp32_t;
+ std::vector<int32_t> input_shape = { 2, 4, 4, 1 };
+ std::vector<int32_t> output_shape = { 2, 2, 2, 1 };
+ std::vector<float> srcData(32);
+ std::vector<float> dstData(8, 0.f);
+ std::iota(std::begin(srcData), std::end(srcData), 1);
+
+ tosa_tensor_t input;
+ input.shape = input_shape.data();
+ input.num_dims = input_shape.size();
+ input.data_type = dt;
+ input.data = reinterpret_cast<uint8_t*>(srcData.data());
+ input.size = srcData.size() * sizeof(float);
+
+ tosa_tensor_t output;
+ output.shape = output_shape.data();
+ output.num_dims = output_shape.size();
+ output.data_type = dt;
+ output.data = reinterpret_cast<uint8_t*>(dstData.data());
+ output.size = dstData.size() * sizeof(float);
+
+ // Execution
+ auto status = tosa_run_max_pool2d(input, kernel, stride, pad, 0, 0, output);
+ CHECK((status == tosa_status_valid));
+
+ // Compare results
+ std::vector<float> expectedData = { 6, 8, 14, 16, 22, 24, 30, 32 };
+ compareOutput(dstData, expectedData, expectedData.size());
+ }
- // Read in inputs and expected outputs.
- inputs[0] = readFromNpyFile<float>(input0_file.c_str(), input0_shape);
- inputs[1] = readFromNpyFile<float>(input1_file.c_str(), input1_shape);
- expected_outputs = readFromNpyFile<float>(expected_output_file.c_str(), output_shape);
+ TEST_CASE("op_entry_pad")
+ {
+ // Inputs/Outputs
+ tosa_datatype_t dt = tosa_datatype_fp32_t;
+ std::vector<int32_t> input_shape = { 2, 2 };
+ std::vector<int32_t> output_shape = { 4, 4 };
+ std::vector<float> srcData1(4, 4.0f);
+ std::vector<float> dstData(16, 0.0f);
+
+ tosa_tensor_t input1;
+ input1.shape = input_shape.data();
+ input1.num_dims = input_shape.size();
+ input1.data_type = dt;
+ input1.data = reinterpret_cast<uint8_t*>(srcData1.data());
+ input1.size = srcData1.size() * sizeof(float);
+
+ tosa_tensor_t output;
+ output.shape = output_shape.data();
+ output.num_dims = output_shape.size();
+ output.data_type = dt;
+ output.data = reinterpret_cast<uint8_t*>(dstData.data());
+ output.size = dstData.size() * sizeof(float);
+
+ // Execution
+ int32_t padding[4] = { 1, 1, 1, 1 };
+ int32_t padding_len = 4;
+ int32_t pad_const_int = 0;
+ float pad_const_fp = 5.0f;
+ auto status = tosa_run_pad(input1, padding_len, padding, pad_const_int, pad_const_fp, output);
+ CHECK((status == tosa_status_valid));
+
+ // Compare results
+ // Expect a 4x4 array with a border of 5's and inner 2x2 of 4's
+ std::vector<float> expectedData(16, 5.0f);
+ expectedData[5] = 4.0f;
+ expectedData[6] = 4.0f;
+ expectedData[9] = 4.0f;
+ expectedData[10] = 4.0f;
+ compareOutput(dstData, expectedData, expectedData.size());
+ }
- TosaSerializationHandler handler;
- tosa_err_t error = handler.LoadFileTosaFlatbuffer(tosa_model_file.c_str());
- CHECK((error == tosa::TOSA_OK));
+ TEST_CASE("simple_add_f32_test")
+ {
+ std::string test_root(std::string(PROJECT_ROOT) + "../examples/test_add_1x4x4x4_f32/");
+ std::string tosa_model_file(test_root + "flatbuffer-tflite/test_add_1x4x4x4_f32.tosa");
+ std::string input0_file(test_root + "placeholder_0.npy");
+ std::string input1_file(test_root + "placeholder_1.npy");
+ std::string expected_output_file(test_root + "tflite_result.npy");
- GraphStatus status;
+ std::vector<std::string> input_names = { "TosaInput_0", "TosaInput_1" };
+ std::string output_name = "TosaOutput_0";
- // Initialize the ModelRunner with configurations.
- IModelRunner runner;
- status = runner.initialize(handler);
- CHECK((status == GraphStatus::TOSA_VALID));
+ std::vector<int32_t> input0_shape = { 1, 4, 4, 1 };
+ std::vector<int32_t> input1_shape = { 1, 4, 4, 4 };
+ std::vector<int32_t> output_shape = { 1, 4, 4, 4 };
- runner.setInput(input_names[0], inputs[0]);
- runner.setInput(input_names[1], inputs[1]);
+ std::vector<std::vector<float>> inputs(input_names.size());
+ std::vector<float> actual_outputs = {};
+ std::vector<float> expected_outputs = {};
- // Run the ModelRunner using test inputs.
- status = runner.run();
- CHECK((status == GraphStatus::TOSA_VALID));
+ // Read in inputs and expected outputs.
+ inputs[0] = readFromNpyFile<float>(input0_file.c_str(), input0_shape);
+ inputs[1] = readFromNpyFile<float>(input1_file.c_str(), input1_shape);
+ expected_outputs = readFromNpyFile<float>(expected_output_file.c_str(), output_shape);
- actual_outputs = runner.getOutput<float>(output_name);
- CHECK(!actual_outputs.empty());
+ TosaSerializationHandler handler;
+ tosa_err_t error = handler.LoadFileTosaFlatbuffer(tosa_model_file.c_str());
+ CHECK((error == tosa::TOSA_OK));
- compareOutput(expected_outputs, actual_outputs, expected_outputs.size());
-}
+ GraphStatus status;
-TEST_CASE("conv2d_f32_test")
-{
- std::string test_root(std::string(PROJECT_ROOT) + "../examples/test_conv2d_1x1_1x32x32x8_f32_st11_padSAME_dilat11/");
- std::string tosa_model_file(test_root + "flatbuffer-tflite/test_conv2d_1x1_1x32x32x8_f32_st11_padSAME_dilat11.tosa");
- std::string input_file(test_root + "placeholder_0.npy");
- std::string expected_output_file(test_root + "tflite_result.npy");
+ // Initialize the ModelRunner with configurations.
+ IModelRunner runner;
+ status = runner.initialize(handler);
+ CHECK((status == GraphStatus::TOSA_VALID));
- std::string input_name = "TosaInput_0";
- std::string output_name = "TosaOutput_0";
+ runner.setInput(input_names[0], inputs[0]);
+ runner.setInput(input_names[1], inputs[1]);
- std::vector<int32_t> input_shape = { 1, 32, 32, 8 };
- std::vector<int32_t> output_shape = { 1, 32, 32, 16 };
+ // Run the ModelRunner using test inputs.
+ status = runner.run();
+ CHECK((status == GraphStatus::TOSA_VALID));
- // Read in inputs and expected outputs.
- std::vector<float> inputs = readFromNpyFile<float>(input_file.c_str(), input_shape);
- std::vector<float> expected_outputs = readFromNpyFile<float>(expected_output_file.c_str(), output_shape);
+ actual_outputs = runner.getOutput<float>(output_name);
+ CHECK(!actual_outputs.empty());
- TosaSerializationHandler handler;
- tosa_err_t error = handler.LoadFileTosaFlatbuffer(tosa_model_file.c_str());
- CHECK((error == tosa::TOSA_OK));
+ compareOutput(expected_outputs, actual_outputs, expected_outputs.size());
+ }
- GraphStatus status;
+ TEST_CASE("conv2d_f32_test")
+ {
+ std::string test_root(std::string(PROJECT_ROOT) +
+ "../examples/test_conv2d_1x1_1x32x32x8_f32_st11_padSAME_dilat11/");
+ std::string tosa_model_file(test_root +
+ "flatbuffer-tflite/test_conv2d_1x1_1x32x32x8_f32_st11_padSAME_dilat11.tosa");
+ std::string input_file(test_root + "placeholder_0.npy");
+ std::string expected_output_file(test_root + "tflite_result.npy");
- // Initialize the ModelRunner with configurations.
- IModelRunner runner;
- status = runner.initialize(handler);
- CHECK((status == GraphStatus::TOSA_VALID));
+ std::string input_name = "TosaInput_0";
+ std::string output_name = "TosaOutput_0";
- runner.setInput(input_name, inputs);
+ std::vector<int32_t> input_shape = { 1, 32, 32, 8 };
+ std::vector<int32_t> output_shape = { 1, 32, 32, 16 };
- // Run the ModelRunner using test inputs.
- status = runner.run();
- CHECK((status == GraphStatus::TOSA_VALID));
+ // Read in inputs and expected outputs.
+ std::vector<float> inputs = readFromNpyFile<float>(input_file.c_str(), input_shape);
+ std::vector<float> expected_outputs = readFromNpyFile<float>(expected_output_file.c_str(), output_shape);
- std::vector<float> actual_outputs = runner.getOutput<float>(output_name);
- CHECK(!actual_outputs.empty());
+ TosaSerializationHandler handler;
+ tosa_err_t error = handler.LoadFileTosaFlatbuffer(tosa_model_file.c_str());
+ CHECK((error == tosa::TOSA_OK));
- compareOutput(expected_outputs, actual_outputs, expected_outputs.size());
-}
+ GraphStatus status;
-TEST_CASE("conv2d_f32_validate_only_test")
-{
- std::string test_root(std::string(PROJECT_ROOT) + "../examples/test_conv2d_1x1_1x32x32x8_f32_st11_padSAME_dilat11/");
- std::string tosa_model_file(test_root + "flatbuffer-tflite/test_conv2d_1x1_1x32x32x8_f32_st11_padSAME_dilat11.tosa");
+ // Initialize the ModelRunner with configurations.
+ IModelRunner runner;
+ status = runner.initialize(handler);
+ CHECK((status == GraphStatus::TOSA_VALID));
- TosaSerializationHandler handler;
- tosa_err_t error = handler.LoadFileTosaFlatbuffer(tosa_model_file.c_str());
- CHECK((error == tosa::TOSA_OK));
+ runner.setInput(input_name, inputs);
- GraphStatus status;
- func_debug_t funcDebug;
+ // Run the ModelRunner using test inputs.
+ status = runner.run();
+ CHECK((status == GraphStatus::TOSA_VALID));
- func_config_t funcConfig;
- funcConfig.validate_only = 1;
+ std::vector<float> actual_outputs = runner.getOutput<float>(output_name);
+ CHECK(!actual_outputs.empty());
- // Initialize the ModelRunner with configurations.
- IModelRunner runner = IModelRunner(funcConfig, funcDebug);
- runner.setFuncConfig(funcConfig);
- status = runner.initialize(handler);
- CHECK((status == GraphStatus::TOSA_VALID));
+ compareOutput(expected_outputs, actual_outputs, expected_outputs.size());
+ }
- // Run the ModelRunner using no inputs, as validate_only is specified run() should still work.
- status = runner.run();
- CHECK((status == GraphStatus::TOSA_VALID));
-}
+ TEST_CASE("conv2d_f32_validate_only_test")
+ {
+ std::string test_root(std::string(PROJECT_ROOT) +
+ "../examples/test_conv2d_1x1_1x32x32x8_f32_st11_padSAME_dilat11/");
+ std::string tosa_model_file(test_root +
+ "flatbuffer-tflite/test_conv2d_1x1_1x32x32x8_f32_st11_padSAME_dilat11.tosa");
+
+ TosaSerializationHandler handler;
+ tosa_err_t error = handler.LoadFileTosaFlatbuffer(tosa_model_file.c_str());
+ CHECK((error == tosa::TOSA_OK));
+
+ GraphStatus status;
+ func_debug_t funcDebug;
+
+ func_config_t funcConfig;
+ funcConfig.validate_only = 1;
+
+ // Initialize the ModelRunner with configurations.
+ IModelRunner runner = IModelRunner(funcConfig, funcDebug);
+ runner.setFuncConfig(funcConfig);
+ status = runner.initialize(handler);
+ CHECK((status == GraphStatus::TOSA_VALID));
+
+ // Run the ModelRunner using no inputs, as validate_only is specified run() should still work.
+ status = runner.run();
+ CHECK((status == GraphStatus::TOSA_VALID));
+ }
-}
+} // TEST_SUITE(model_runner)