aboutsummaryrefslogtreecommitdiff
path: root/compute_kernel_writer/validation/tests/CLTensorArgumentTest.h
diff options
context:
space:
mode:
Diffstat (limited to 'compute_kernel_writer/validation/tests/CLTensorArgumentTest.h')
-rw-r--r--compute_kernel_writer/validation/tests/CLTensorArgumentTest.h540
1 files changed, 540 insertions, 0 deletions
diff --git a/compute_kernel_writer/validation/tests/CLTensorArgumentTest.h b/compute_kernel_writer/validation/tests/CLTensorArgumentTest.h
new file mode 100644
index 0000000000..d3e455cb83
--- /dev/null
+++ b/compute_kernel_writer/validation/tests/CLTensorArgumentTest.h
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 2023 Arm Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef CKW_VALIDATION_TESTS_CLTENSORARGUMENTTEST_H
+#define CKW_VALIDATION_TESTS_CLTENSORARGUMENTTEST_H
+
+#include "common/Common.h"
+#include "src/cl/CLHelpers.h"
+#include "src/cl/CLTensorArgument.h"
+#include "src/cl/CLTensorComponent.h"
+
+#include <string>
+#include <vector>
+
+namespace ckw
+{
+class CLTensorArgumentComponentNamesTest : public ITest
+{
+public:
+ const DataType dt = DataType::Fp32;
+ const TensorShape shape = TensorShape({ { 12, 14, 3, 1, 2 } });
+ const std::string tensor_name = "src";
+
+ CLTensorArgumentComponentNamesTest()
+ {
+ _components.push_back(TensorComponentType::Dim0);
+ _components.push_back(TensorComponentType::Dim1);
+ _components.push_back(TensorComponentType::Dim2);
+ _components.push_back(TensorComponentType::Dim3);
+ _components.push_back(TensorComponentType::Dim4);
+ _components.push_back(TensorComponentType::Dim1xDim2);
+ _components.push_back(TensorComponentType::Dim2xDim3);
+ _components.push_back(TensorComponentType::OffsetFirstElement);
+ _components.push_back(TensorComponentType::Stride0);
+ _components.push_back(TensorComponentType::Stride1);
+ _components.push_back(TensorComponentType::Stride2);
+ _components.push_back(TensorComponentType::Stride3);
+ _components.push_back(TensorComponentType::Stride4);
+
+ _expected_vars.push_back("src_dim0");
+ _expected_vars.push_back("src_dim1");
+ _expected_vars.push_back("src_dim2");
+ _expected_vars.push_back("src_dim3");
+ _expected_vars.push_back("src_dim4");
+ _expected_vars.push_back("src_dim1xdim2");
+ _expected_vars.push_back("src_dim2xdim3");
+ _expected_vars.push_back("src_offset_first_element");
+ _expected_vars.push_back("src_stride0");
+ _expected_vars.push_back("src_stride1");
+ _expected_vars.push_back("src_stride2");
+ _expected_vars.push_back("src_stride3");
+ _expected_vars.push_back("src_stride4");
+ }
+
+ bool run() override
+ {
+ VALIDATE_ON_MSG(_components.size() == _expected_vars.size(), "The number of components and variables does not match");
+
+ // The status of this variable can change in VALIDATE_TEST()
+ bool all_tests_passed = true;
+
+ const TensorInfo info(dt, shape, TensorDataLayout::Nhwc, 1);
+
+ const size_t num_tests = _expected_vars.size();
+
+ int32_t test_idx = 0;
+ for(size_t i = 0; i < num_tests; ++i)
+ {
+ CLTensorArgument arg(tensor_name, info, false /* return_dims_by_value */);
+
+ const std::string expected_var_name = _expected_vars[i];
+ const std::string actual_var_name = arg.component(_components[i]).name();
+
+ VALIDATE_TEST(actual_var_name.compare(expected_var_name) == 0, all_tests_passed, test_idx++);
+ }
+ return all_tests_passed;
+ }
+
+ std::string name() override
+ {
+ return "CLTensorArgumentVariableNamesTest";
+ }
+
+private:
+ std::vector<TensorComponentType> _components{};
+ std::vector<std::string> _expected_vars{};
+};
+
+class CLTensorArgumentStorageNamesTest : public ITest
+{
+public:
+ const DataType dt = DataType::Fp32;
+ const TensorShape shape = TensorShape({ { 12, 14, 3, 1, 2 } });
+ const std::string tensor_name = "src";
+
+ CLTensorArgumentStorageNamesTest()
+ {
+ _storages.push_back(TensorStorageType::BufferUint8Ptr);
+ _storages.push_back(TensorStorageType::Texture2dReadOnly);
+ _storages.push_back(TensorStorageType::Texture2dWriteOnly);
+
+ _expected_vars.push_back("src_ptr");
+ _expected_vars.push_back("src_img2d");
+ _expected_vars.push_back("src_img2d");
+ }
+
+ bool run() override
+ {
+ VALIDATE_ON_MSG(_storages.size() == _expected_vars.size(), "The number of storages and variables does not match");
+
+ // The status of this variable can change in VALIDATE_TEST()
+ bool all_tests_passed = true;
+
+ const TensorInfo info(dt, shape, TensorDataLayout::Nhwc, 1);
+
+ const size_t num_tests = _expected_vars.size();
+
+ int32_t test_idx = 0;
+ for(size_t i = 0; i < num_tests; ++i)
+ {
+ CLTensorArgument arg(tensor_name, info, false /* return_dims_by_value */);
+
+ const std::string expected_var_name = _expected_vars[i];
+ const std::string actual_var_name = arg.storage(_storages[i]).val;
+
+ VALIDATE_TEST(actual_var_name.compare(expected_var_name) == 0, all_tests_passed, test_idx++);
+ }
+ return all_tests_passed;
+ }
+
+ std::string name() override
+ {
+ return "CLTensorArgumentStorageNamesTest";
+ }
+
+private:
+ std::vector<TensorStorageType> _storages{};
+ std::vector<std::string> _expected_vars{};
+};
+
+class CLTensorArgumentComponentValuesTest : public ITest
+{
+public:
+ const DataType dt = DataType::Fp32;
+ const TensorShape shape = TensorShape({ { 12, 14, 3, 1, 2 } });
+ const std::string tensor_name = "src";
+
+ CLTensorArgumentComponentValuesTest()
+ {
+ _components.push_back(TensorComponentType::Dim0);
+ _components.push_back(TensorComponentType::Dim1);
+ _components.push_back(TensorComponentType::Dim2);
+ _components.push_back(TensorComponentType::Dim3);
+ _components.push_back(TensorComponentType::Dim4);
+ _components.push_back(TensorComponentType::Dim1xDim2);
+ _components.push_back(TensorComponentType::Dim2xDim3);
+
+ _expected_vals.push_back(std::to_string(shape[0]));
+ _expected_vals.push_back(std::to_string(shape[1]));
+ _expected_vals.push_back(std::to_string(shape[2]));
+ _expected_vals.push_back(std::to_string(shape[3]));
+ _expected_vals.push_back(std::to_string(shape[4]));
+ _expected_vals.push_back(std::to_string(shape[1] * shape[2]));
+ _expected_vals.push_back(std::to_string(shape[2] * shape[3]));
+ }
+
+ bool run() override
+ {
+ VALIDATE_ON_MSG(_components.size() == _expected_vals.size(), "The number of components and values does not match");
+
+ // The status of this variable can change in VALIDATE_TEST()
+ bool all_tests_passed = true;
+
+ const TensorInfo info(dt, shape, TensorDataLayout::Nhwc, 1);
+
+ const size_t num_tests = _expected_vals.size();
+
+ int32_t test_idx = 0;
+ for(size_t i = 0; i < num_tests; ++i)
+ {
+ CLTensorArgument arg(tensor_name, info, true /* return_dims_by_value */);
+
+ const std::string expected_var_val = std::string("((int)(") + _expected_vals[i] + "))";
+ const std::string actual_var_val = arg.cl_component(_components[i]).scalar(0, 0).str;
+
+ VALIDATE_TEST(actual_var_val.compare(expected_var_val) == 0, all_tests_passed, test_idx++);
+ }
+ return all_tests_passed;
+ }
+
+ std::string name() override
+ {
+ return "CLTensorArgumentComponentValuesTest";
+ }
+
+private:
+ std::vector<TensorComponentType> _components{};
+ std::vector<std::string> _expected_vals{};
+};
+
+class CLTensorArgumentComponentsUsedPassByValueFalseTest : public ITest
+{
+public:
+ const DataType dt = DataType::Fp32;
+ const TensorShape shape = TensorShape({ { 12, 14, 3, 1, 2 } });
+ const std::string tensor_name = "src";
+
+ CLTensorArgumentComponentsUsedPassByValueFalseTest()
+ {
+ _components.push_back(TensorComponentType::Dim0);
+ _components.push_back(TensorComponentType::Dim2);
+ _components.push_back(TensorComponentType::Dim3);
+ _components.push_back(TensorComponentType::Dim1xDim2);
+ _components.push_back(TensorComponentType::OffsetFirstElement);
+ _components.push_back(TensorComponentType::Stride1);
+ _components.push_back(TensorComponentType::Stride2);
+ _components.push_back(TensorComponentType::Stride3);
+ _components.push_back(TensorComponentType::Dim0); // Repeat the query. The TensorArgument should not create a new variable
+ _components.push_back(TensorComponentType::Dim2); // Repeat the query. The TensorArgument should not create a new variable
+ _components.push_back(TensorComponentType::Dim3); // Repeat the query. The TensorArgument should not create a new variable
+
+ _expected_vars.push_back("src_dim0");
+ _expected_vars.push_back("src_dim2");
+ _expected_vars.push_back("src_dim3");
+ _expected_vars.push_back("src_dim1xdim2");
+ _expected_vars.push_back("src_offset_first_element");
+ _expected_vars.push_back("src_stride1");
+ _expected_vars.push_back("src_stride2");
+ _expected_vars.push_back("src_stride3");
+ }
+
+ bool run() override
+ {
+ // The status of this variable can change in VALIDATE_TEST()
+ bool all_tests_passed = true;
+
+ const TensorInfo info(dt, shape, TensorDataLayout::Nhwc, 1);
+
+ const size_t num_components = _components.size();
+
+ int32_t test_idx = 0;
+
+ CLTensorArgument arg(tensor_name, info, false /* return_dims_by_value */);
+ for(size_t i = 0; i < num_components; ++i)
+ {
+ arg.component(_components[i]);
+ }
+
+ const auto actual_vars = arg.components();
+
+ const size_t num_vars = _expected_vars.size();
+
+ VALIDATE_ON_MSG(actual_vars.size() == num_vars, "The number of variables must match the number of expected variables");
+
+ for(size_t i = 0; i < num_vars; ++i)
+ {
+ // Validate variable name
+ const std::string expected_var_name = _expected_vars[i];
+ const std::string actual_var_name = actual_vars[i]->tile().name();
+ VALIDATE_TEST(actual_var_name.compare(expected_var_name) == 0, all_tests_passed, test_idx++);
+
+ // Validate data type
+ const DataType expected_var_type = DataType::Int32;
+ const DataType actual_var_type = actual_vars[i]->tile().info().data_type();
+ VALIDATE_TEST(actual_var_type == expected_var_type, all_tests_passed, test_idx++);
+
+ // Validate tile shape
+ const int32_t actual_var_width = actual_vars[i]->tile().info().width();
+ const int32_t actual_var_height = actual_vars[i]->tile().info().height();
+
+ VALIDATE_TEST(actual_var_height == 1, all_tests_passed, test_idx++);
+ VALIDATE_TEST(actual_var_width == 1, all_tests_passed, test_idx++);
+ }
+ return all_tests_passed;
+ }
+
+ std::string name() override
+ {
+ return "CLTensorArgumentComponentsUsedPassByValueFalseTest";
+ }
+
+private:
+ std::vector<TensorComponentType> _components{};
+ std::vector<std::string> _expected_vars{};
+};
+
+class CLTensorArgumentComponentsUsedPassByValueTrueTest : public ITest
+{
+public:
+ const DataType dt = DataType::Fp32;
+ const TensorShape shape = TensorShape({ { 12, 14, 3, 1, 2 } });
+ const std::string tensor_name = "src";
+
+ CLTensorArgumentComponentsUsedPassByValueTrueTest()
+ {
+ _components.push_back(TensorComponentType::Dim0);
+ _components.push_back(TensorComponentType::Dim2);
+ _components.push_back(TensorComponentType::Dim3);
+ _components.push_back(TensorComponentType::Dim1xDim2);
+ _components.push_back(TensorComponentType::OffsetFirstElement);
+ _components.push_back(TensorComponentType::Stride1);
+ _components.push_back(TensorComponentType::Stride2);
+ _components.push_back(TensorComponentType::Stride3);
+ _components.push_back(TensorComponentType::OffsetFirstElement); // Repeat the query. The TensorArgument should not create a new variable
+ _components.push_back(TensorComponentType::Stride1); // Repeat the query. The TensorArgument should not create a new variable
+
+ _expected_vars.push_back("src_offset_first_element");
+ _expected_vars.push_back("src_stride1");
+ _expected_vars.push_back("src_stride2");
+ _expected_vars.push_back("src_stride3");
+ }
+
+ bool run() override
+ {
+ // The status of this variable can change in VALIDATE_TEST()
+ bool all_tests_passed = true;
+
+ const TensorInfo info(dt, shape, TensorDataLayout::Nhwc, 1);
+
+ const size_t num_components = _components.size();
+
+ int32_t test_idx = 0;
+
+ CLTensorArgument arg(tensor_name, info, true /* return_dims_by_value */);
+ for(size_t i = 0; i < num_components; ++i)
+ {
+ arg.component(_components[i]);
+ }
+
+ const auto actual_vars = arg.components();
+
+ const size_t num_vars = _expected_vars.size();
+
+ VALIDATE_ON_MSG(actual_vars.size() == num_vars, "The number of variables must match the number of expected variables");
+
+ // Since the dimensions are passed by value, we expect only the variables for the strides
+ for(size_t i = 0; i < num_vars; ++i)
+ {
+ // Validate variable name
+ const std::string expected_var_name = _expected_vars[i];
+ const std::string actual_var_name = actual_vars[i]->tile().name();
+ VALIDATE_TEST(actual_var_name.compare(expected_var_name) == 0, all_tests_passed, test_idx++);
+
+ // Validate data type
+ const DataType expected_var_type = DataType::Int32;
+ const DataType actual_var_type = actual_vars[i]->tile().info().data_type();
+ VALIDATE_TEST(actual_var_type == expected_var_type, all_tests_passed, test_idx++);
+
+ // Validate tile shape
+ const int32_t actual_var_width = actual_vars[i]->tile().info().width();
+ const int32_t actual_var_height = actual_vars[i]->tile().info().height();
+
+ VALIDATE_TEST(actual_var_height == 1, all_tests_passed, test_idx++);
+ VALIDATE_TEST(actual_var_width == 1, all_tests_passed, test_idx++);
+ }
+ return all_tests_passed;
+ }
+
+ std::string name() override
+ {
+ return "CLTensorArgumentComponentsUsedPassByValueTrueTest";
+ }
+
+private:
+ std::vector<TensorComponentType> _components{};
+ std::vector<std::string> _expected_vars{};
+};
+
+class CLTensorArgumentStoragesUsedTest : public ITest
+{
+public:
+ const DataType dt = DataType::Fp32;
+ const TensorShape shape = TensorShape({ { 12, 14, 3, 1, 2 } });
+ const std::string tensor_name = "src";
+
+ CLTensorArgumentStoragesUsedTest()
+ {
+ _storages.push_back(TensorStorageType::BufferUint8Ptr);
+ _storages.push_back(TensorStorageType::Texture2dReadOnly);
+ _storages.push_back(TensorStorageType::BufferUint8Ptr); // Repeat the query. The TensorArgument should not create a new variable
+
+ _expected_vars.push_back("src_ptr");
+ _expected_vars.push_back("src_img2d");
+ }
+
+ bool run() override
+ {
+ // The status of this variable can change in VALIDATE_TEST()
+ bool all_tests_passed = true;
+
+ const TensorInfo info(dt, shape, TensorDataLayout::Nhwc, 1);
+
+ const size_t num_storages = _storages.size();
+
+ int32_t test_idx = 0;
+
+ CLTensorArgument arg(tensor_name, info, true /* return_dims_by_value */);
+ for(size_t i = 0; i < num_storages; ++i)
+ {
+ arg.storage(_storages[i]);
+ }
+
+ const auto actual_vars = arg.storages();
+
+ const size_t num_vars = _expected_vars.size();
+
+ VALIDATE_ON_MSG(actual_vars.size() == num_vars, "The number of variables must match the number of expected variables");
+
+ for(size_t i = 0; i < num_vars; ++i)
+ {
+ // Validate variable name
+ const std::string expected_var_name = _expected_vars[i];
+ const std::string actual_var_name = actual_vars[i].val;
+ VALIDATE_TEST(actual_var_name.compare(expected_var_name) == 0, all_tests_passed, test_idx++);
+
+ // Validate storage type
+ const auto expected_var_type = _storages[i];
+ const auto actual_var_type = actual_vars[i].type;
+ VALIDATE_TEST(actual_var_type == expected_var_type, all_tests_passed, test_idx++);
+ }
+ return all_tests_passed;
+ }
+
+ std::string name() override
+ {
+ return "CLTensorArgumentStoragesUsedTest";
+ }
+
+private:
+ std::vector<TensorStorageType> _storages{};
+ std::vector<std::string> _expected_vars{};
+};
+
+class CLTensorArgumentComponentsUsedPassByValueTrueDynamicDimTrueTest : public ITest
+{
+public:
+ const DataType dt = DataType::Fp32;
+ const TensorShape shape = TensorShape({ { -1, -1, 3, 1, 2 } });
+ const std::string tensor_name = "src";
+
+ CLTensorArgumentComponentsUsedPassByValueTrueDynamicDimTrueTest()
+ {
+ _components.push_back(TensorComponentType::Dim0);
+ _components.push_back(TensorComponentType::Dim2);
+ _components.push_back(TensorComponentType::Dim3);
+ _components.push_back(TensorComponentType::Dim1xDim2);
+ _components.push_back(TensorComponentType::OffsetFirstElement);
+ _components.push_back(TensorComponentType::Stride1);
+ _components.push_back(TensorComponentType::Stride2);
+ _components.push_back(TensorComponentType::Stride3);
+ _components.push_back(TensorComponentType::OffsetFirstElement); // Repeat the query. The TensorArgument should not create a new variable
+ _components.push_back(TensorComponentType::Stride1); // Repeat the query. The TensorArgument should not create a new variable
+
+ _expected_vars.push_back("src_dim0");
+ _expected_vars.push_back("src_dim1xdim2");
+ _expected_vars.push_back("src_offset_first_element");
+ _expected_vars.push_back("src_stride1");
+ _expected_vars.push_back("src_stride2");
+ _expected_vars.push_back("src_stride3");
+ }
+
+ bool run() override
+ {
+ // The status of this variable can change in VALIDATE_TEST()
+ bool all_tests_passed = true;
+
+ const TensorInfo info(dt, shape, TensorDataLayout::Nhwc, 1);
+
+ const size_t num_components = _components.size();
+
+ int32_t test_idx = 0;
+
+ CLTensorArgument arg(tensor_name, info, true /* return_dims_by_value */);
+ for(size_t i = 0; i < num_components; ++i)
+ {
+ arg.component(_components[i]);
+ }
+
+ const auto actual_vars = arg.components();
+
+ const size_t num_vars = _expected_vars.size();
+
+ VALIDATE_ON_MSG(actual_vars.size() == num_vars, "The number of variables must match the number of expected variables");
+
+ // Since the dimensions are passed by value, we expect only the variables for the strides
+ for(size_t i = 0; i < num_vars; ++i)
+ {
+ // Validate variable name
+ const std::string expected_var_name = _expected_vars[i];
+ const std::string actual_var_name = actual_vars[i]->tile().name();
+ VALIDATE_TEST(actual_var_name.compare(expected_var_name) == 0, all_tests_passed, test_idx++);
+
+ // Validate data type
+ const DataType expected_var_type = DataType::Int32;
+ const DataType actual_var_type = actual_vars[i]->tile().info().data_type();
+ VALIDATE_TEST(actual_var_type == expected_var_type, all_tests_passed, test_idx++);
+
+ // Validate tile shape
+ const int32_t actual_var_width = actual_vars[i]->tile().info().width();
+ const int32_t actual_var_height = actual_vars[i]->tile().info().height();
+
+ VALIDATE_TEST(actual_var_height == 1, all_tests_passed, test_idx++);
+ VALIDATE_TEST(actual_var_width == 1, all_tests_passed, test_idx++);
+ }
+ return all_tests_passed;
+ }
+
+ std::string name() override
+ {
+ return "CLTensorArgumentComponentsUsedPassByValueTrueDynamicDimTrueTest";
+ }
+
+private:
+ std::vector<TensorComponentType> _components{};
+ std::vector<std::string> _expected_vars{};
+};
+} // namespace ckw
+
+#endif // CKW_VALIDATION_TESTS_CLTENSORARGUMENTTEST_H