diff options
Diffstat (limited to 'framework')
-rw-r--r-- | framework/DatasetModes.cpp | 54 | ||||
-rw-r--r-- | framework/DatasetModes.h | 106 | ||||
-rw-r--r-- | framework/Framework.cpp | 31 | ||||
-rw-r--r-- | framework/Framework.h | 24 | ||||
-rw-r--r-- | framework/Macros.h | 32 | ||||
-rw-r--r-- | framework/Registrars.h | 15 | ||||
-rw-r--r-- | framework/TestCaseFactory.h | 27 |
7 files changed, 247 insertions, 42 deletions
diff --git a/framework/DatasetModes.cpp b/framework/DatasetModes.cpp new file mode 100644 index 0000000000..0a9e92a38b --- /dev/null +++ b/framework/DatasetModes.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 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. + */ +#include "DatasetModes.h" + +#include <map> + +namespace arm_compute +{ +namespace test +{ +namespace framework +{ +DatasetMode dataset_mode_from_name(const std::string &name) +{ + static const std::map<std::string, DatasetMode> modes = + { + { "all", DatasetMode::ALL }, + { "precommit", DatasetMode::PRECOMMIT }, + { "nightly", DatasetMode::NIGHTLY }, + }; + + try + { + return modes.at(name); + } + catch(const std::out_of_range &) + { + throw std::invalid_argument(name); + } +} +} // namespace framework +} // namespace test +} // namespace arm_compute diff --git a/framework/DatasetModes.h b/framework/DatasetModes.h new file mode 100644 index 0000000000..27638b0504 --- /dev/null +++ b/framework/DatasetModes.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2017 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 ARM_COMPUTE_TEST_DATASET_MODES +#define ARM_COMPUTE_TEST_DATASET_MODES + +#include <istream> +#include <ostream> +#include <sstream> +#include <stdexcept> +#include <string> + +namespace arm_compute +{ +namespace test +{ +namespace framework +{ +/** Possible dataset modes. */ +enum class DatasetMode : unsigned int +{ + ALL = ~0U, + DISABLED = 0, + PRECOMMIT = 1, + NIGHTLY = 2 +}; + +inline DatasetMode operator&(DatasetMode t1, DatasetMode t2) +{ + using type = std::underlying_type<DatasetMode>::type; + return static_cast<DatasetMode>(static_cast<type>(t1) & static_cast<type>(t2)); +} + +inline DatasetMode operator|(DatasetMode t1, DatasetMode t2) +{ + using type = std::underlying_type<DatasetMode>::type; + return static_cast<DatasetMode>(static_cast<type>(t1) | static_cast<type>(t2)); +} + +inline DatasetMode &operator|=(DatasetMode &t1, DatasetMode t2) +{ + using type = std::underlying_type<DatasetMode>::type; + t1 = static_cast<DatasetMode>(static_cast<type>(t1) | static_cast<type>(t2)); + return t1; +} + +DatasetMode dataset_mode_from_name(const std::string &name); + +inline ::std::istream &operator>>(::std::istream &stream, DatasetMode &mode) +{ + std::string value; + stream >> value; + mode = dataset_mode_from_name(value); + return stream; +} + +inline ::std::ostream &operator<<(::std::ostream &stream, DatasetMode mode) +{ + switch(mode) + { + case DatasetMode::PRECOMMIT: + stream << "PRECOMMIT"; + break; + case DatasetMode::NIGHTLY: + stream << "NIGHTLY"; + break; + case DatasetMode::ALL: + stream << "ALL"; + break; + default: + throw std::invalid_argument("Unsupported dataset mode"); + } + + return stream; +} + +inline std::string to_string(DatasetMode mode) +{ + std::stringstream stream; + stream << mode; + return stream.str(); +} +} // namespace framework +} // namespace test +} // namespace arm_compute +#endif /* ARM_COMPUTE_TEST_DATASET_MODES */ diff --git a/framework/Framework.cpp b/framework/Framework.cpp index 72fa1981fc..c25b3e5d4c 100644 --- a/framework/Framework.cpp +++ b/framework/Framework.cpp @@ -92,11 +92,12 @@ Framework &Framework::get() return instance; } -void Framework::init(const std::vector<InstrumentType> &instruments, int num_iterations, const std::string &name_filter, const std::string &id_filter) +void Framework::init(const std::vector<InstrumentType> &instruments, int num_iterations, DatasetMode mode, const std::string &name_filter, const std::string &id_filter) { _test_name_filter = std::regex{ name_filter }; _test_id_filter = std::regex{ id_filter }; _num_iterations = num_iterations; + _dataset_mode = mode; _instruments = InstrumentType::NONE; @@ -170,7 +171,27 @@ bool Framework::throw_errors() const bool Framework::is_enabled(const TestId &id) const { - return (std::regex_search(support::cpp11::to_string(id.first), _test_id_filter) && std::regex_search(id.second, _test_name_filter)); + int test_id = 0; + std::string name; + DatasetMode mode = DatasetMode::ALL; + std::tie(test_id, name, mode) = id; + + if((mode & _dataset_mode) == DatasetMode::DISABLED) + { + return false; + } + + if(!std::regex_search(support::cpp11::to_string(test_id), _test_id_filter)) + { + return false; + } + + if(!std::regex_search(name, _test_name_filter)) + { + return false; + } + + return true; } void Framework::run_test(TestCaseFactory &test_factory) @@ -276,7 +297,7 @@ bool Framework::run() { const std::string test_case_name = test_factory->name(); - if(!is_enabled(TestId(id, test_case_name))) + if(!is_enabled(TestId(id, test_case_name, test_factory->mode()))) { log_test_skipped(test_case_name); } @@ -355,9 +376,9 @@ std::vector<Framework::TestId> Framework::test_ids() const for(const auto &factory : _test_factories) { - if(is_enabled(TestId(id, factory->name()))) + if(is_enabled(TestId(id, factory->name(), factory->mode()))) { - ids.emplace_back(id, factory->name()); + ids.emplace_back(id, factory->name(), factory->mode()); } ++id; diff --git a/framework/Framework.h b/framework/Framework.h index fbb6b9c04c..a7d8a15541 100644 --- a/framework/Framework.h +++ b/framework/Framework.h @@ -24,6 +24,7 @@ #ifndef ARM_COMPUTE_TEST_FRAMEWORK #define ARM_COMPUTE_TEST_FRAMEWORK +#include "DatasetModes.h" #include "Profiler.h" #include "TestCase.h" #include "TestCaseFactory.h" @@ -60,12 +61,13 @@ class Framework final public: /** Type of a test identifier. * - * A test can be identified either via its id or via its name. + * A test can be identified either via its id or via its name. Additionally + * each test is tagged with the data set mode in which it will be used. * * @note The mapping between test id and test name is not guaranteed to be * stable. It is subject to change as new test are added. */ - using TestId = std::pair<int, std::string>; + using TestId = std::tuple<int, std::string, DatasetMode>; /** Access to the singleton. * @@ -83,10 +85,11 @@ public: * * @param[in] instruments Instrument types that will be used for benchmarking. * @param[in] num_iterations Number of iterations per test. + * @param[in] mode Dataset mode. * @param[in] name_filter Regular expression to filter tests by name. Only matching tests will be executed. * @param[in] id_filter Regular expression to filter tests by id. Only matching tests will be executed. */ - void init(const std::vector<InstrumentType> &instruments, int num_iterations, const std::string &name_filter, const std::string &id_filter); + void init(const std::vector<InstrumentType> &instruments, int num_iterations, DatasetMode mode, const std::string &name_filter, const std::string &id_filter); /** Add a new test suite. * @@ -109,18 +112,20 @@ public: /** Add a test case to the framework. * * @param[in] test_name Name of the new test case. + * @param[in] mode Mode in which to include the test. */ template <typename T> - void add_test_case(std::string test_name); + void add_test_case(std::string test_name, DatasetMode mode); /** Add a data test case to the framework. * * @param[in] test_name Name of the new test case. + * @param[in] mode Mode in which to include the test. * @param[in] description Description of @p data. * @param[in] data Data that will be used as input to the test. */ template <typename T, typename D> - void add_data_test_case(std::string test_name, std::string description, D &&data); + void add_data_test_case(std::string test_name, DatasetMode mode, std::string description, D &&data); /** Tell the framework that execution of a test starts. * @@ -255,21 +260,22 @@ private: InstrumentType _instruments{ InstrumentType::NONE }; std::regex _test_name_filter{ ".*" }; std::regex _test_id_filter{ ".*" }; + DatasetMode _dataset_mode{ DatasetMode::ALL }; }; template <typename T> -inline void Framework::add_test_case(std::string test_name) +inline void Framework::add_test_case(std::string test_name, DatasetMode mode) { - _test_factories.emplace_back(support::cpp14::make_unique<SimpleTestCaseFactory<T>>(current_suite_name(), std::move(test_name))); + _test_factories.emplace_back(support::cpp14::make_unique<SimpleTestCaseFactory<T>>(current_suite_name(), std::move(test_name), mode)); } template <typename T, typename D> -inline void Framework::add_data_test_case(std::string test_name, std::string description, D &&data) +inline void Framework::add_data_test_case(std::string test_name, DatasetMode mode, std::string description, D &&data) { // WORKAROUND for GCC 4.9 // The function should get *it which is tuple but that seems to trigger a // bug in the compiler. - auto tmp = std::unique_ptr<DataTestCaseFactory<T, decltype(*std::declval<D>())>>(new DataTestCaseFactory<T, decltype(*std::declval<D>())>(current_suite_name(), std::move(test_name), + auto tmp = std::unique_ptr<DataTestCaseFactory<T, decltype(*std::declval<D>())>>(new DataTestCaseFactory<T, decltype(*std::declval<D>())>(current_suite_name(), std::move(test_name), mode, std::move(description), *data)); _test_factories.emplace_back(std::move(tmp)); } diff --git a/framework/Macros.h b/framework/Macros.h index e3ef71ac56..38eb29c6a1 100644 --- a/framework/Macros.h +++ b/framework/Macros.h @@ -76,28 +76,28 @@ { \ FIXTURE::teardown(); \ } -#define TEST_REGISTRAR(TEST_NAME) \ +#define TEST_REGISTRAR(TEST_NAME, MODE) \ static arm_compute::test::framework::detail::TestCaseRegistrar<TEST_NAME> TEST_NAME##_reg \ { \ - #TEST_NAME \ + #TEST_NAME, MODE \ } -#define DATA_TEST_REGISTRAR(TEST_NAME, DATASET) \ +#define DATA_TEST_REGISTRAR(TEST_NAME, MODE, DATASET) \ static arm_compute::test::framework::detail::TestCaseRegistrar<TEST_NAME> TEST_NAME##_reg \ { \ - #TEST_NAME, DATASET \ + #TEST_NAME, MODE, DATASET \ } -#define TEST_CASE(TEST_NAME) \ +#define TEST_CASE(TEST_NAME, MODE) \ class TEST_NAME : public arm_compute::test::framework::TestCase \ { \ public: \ TEST_CASE_CONSTRUCTOR(TEST_NAME) \ void do_run() override; \ }; \ - TEST_REGISTRAR(TEST_NAME); \ + TEST_REGISTRAR(TEST_NAME, MODE); \ void TEST_NAME::do_run() -#define DATA_TEST_CASE(TEST_NAME, DATASET, ...) \ +#define DATA_TEST_CASE(TEST_NAME, MODE, DATASET, ...) \ class TEST_NAME : public arm_compute::test::framework::DataTestCase<decltype(DATASET)::type> \ { \ public: \ @@ -108,10 +108,10 @@ } \ void run(__VA_ARGS__); \ }; \ - DATA_TEST_REGISTRAR(TEST_NAME, DATASET); \ + DATA_TEST_REGISTRAR(TEST_NAME, MODE, DATASET); \ void TEST_NAME::run(__VA_ARGS__) -#define FIXTURE_TEST_CASE(TEST_NAME, FIXTURE) \ +#define FIXTURE_TEST_CASE(TEST_NAME, FIXTURE, MODE) \ class TEST_NAME : public arm_compute::test::framework::TestCase, public FIXTURE \ { \ public: \ @@ -120,10 +120,10 @@ void do_run() override; \ FIXTURE_TEARDOWN(FIXTURE) \ }; \ - TEST_REGISTRAR(TEST_NAME); \ + TEST_REGISTRAR(TEST_NAME, MODE); \ void TEST_NAME::do_run() -#define FIXTURE_DATA_TEST_CASE(TEST_NAME, FIXTURE, DATASET) \ +#define FIXTURE_DATA_TEST_CASE(TEST_NAME, FIXTURE, MODE, DATASET) \ class TEST_NAME : public arm_compute::test::framework::DataTestCase<decltype(DATASET)::type>, public FIXTURE \ { \ public: \ @@ -132,10 +132,10 @@ void do_run() override; \ FIXTURE_TEARDOWN(FIXTURE) \ }; \ - DATA_TEST_REGISTRAR(TEST_NAME, DATASET); \ + DATA_TEST_REGISTRAR(TEST_NAME, MODE, DATASET); \ void TEST_NAME::do_run() -#define REGISTER_FIXTURE_TEST_CASE(TEST_NAME, FIXTURE) \ +#define REGISTER_FIXTURE_TEST_CASE(TEST_NAME, FIXTURE, MODE) \ class TEST_NAME : public arm_compute::test::framework::TestCase, public FIXTURE \ { \ public: \ @@ -144,9 +144,9 @@ FIXTURE_RUN(FIXTURE) \ FIXTURE_TEARDOWN(FIXTURE) \ }; \ - TEST_REGISTRAR(TEST_NAME) + TEST_REGISTRAR(TEST_NAME, MODE) -#define REGISTER_FIXTURE_DATA_TEST_CASE(TEST_NAME, FIXTURE, DATASET) \ +#define REGISTER_FIXTURE_DATA_TEST_CASE(TEST_NAME, FIXTURE, MODE, DATASET) \ class TEST_NAME : public arm_compute::test::framework::DataTestCase<decltype(DATASET)::type>, public FIXTURE \ { \ public: \ @@ -155,7 +155,7 @@ FIXTURE_RUN(FIXTURE) \ FIXTURE_TEARDOWN(FIXTURE) \ }; \ - DATA_TEST_REGISTRAR(TEST_NAME, DATASET) + DATA_TEST_REGISTRAR(TEST_NAME, MODE, DATASET) // // TEST CASE MACROS END // diff --git a/framework/Registrars.h b/framework/Registrars.h index 19064c07f5..ddbffabee4 100644 --- a/framework/Registrars.h +++ b/framework/Registrars.h @@ -24,6 +24,7 @@ #ifndef ARM_COMPUTE_TEST_FRAMEWORK_REGISTRARS #define ARM_COMPUTE_TEST_FRAMEWORK_REGISTRARS +#include "DatasetModes.h" #include "Framework.h" #include <string> @@ -45,16 +46,18 @@ public: /** Add a new test case with the given name to the framework. * * @param[in] test_name Name of the test case. + * @param[in] mode Mode in which the test should be activated. */ - TestCaseRegistrar(std::string test_name); + TestCaseRegistrar(std::string test_name, DatasetMode mode); /** Add a new data test case with the given name to the framework. * * @param[in] test_name Name of the test case. + * @param[in] mode Mode in which the test should be activated. * @param[in] dataset Dataset used as input for the test case. */ template <typename D> - TestCaseRegistrar(std::string test_name, D &&dataset); + TestCaseRegistrar(std::string test_name, DatasetMode mode, D &&dataset); }; /** Helper class to statically begin and end a test suite. */ @@ -72,14 +75,14 @@ public: }; template <typename T> -inline TestCaseRegistrar<T>::TestCaseRegistrar(std::string test_name) +inline TestCaseRegistrar<T>::TestCaseRegistrar(std::string test_name, DatasetMode mode) { - Framework::get().add_test_case<T>(std::move(test_name)); + Framework::get().add_test_case<T>(std::move(test_name), mode); } template <typename T> template <typename D> -inline TestCaseRegistrar<T>::TestCaseRegistrar(std::string test_name, D &&dataset) +inline TestCaseRegistrar<T>::TestCaseRegistrar(std::string test_name, DatasetMode mode, D &&dataset) { auto it = dataset.begin(); @@ -88,7 +91,7 @@ inline TestCaseRegistrar<T>::TestCaseRegistrar(std::string test_name, D &&datase // WORKAROUND for GCC 4.9 // The last argument should be *it to pass just the data and not the // iterator. - Framework::get().add_data_test_case<T>(test_name, it.description(), it); + Framework::get().add_data_test_case<T>(test_name, mode, it.description(), it); } } diff --git a/framework/TestCaseFactory.h b/framework/TestCaseFactory.h index 09e9d198d6..e275e298d6 100644 --- a/framework/TestCaseFactory.h +++ b/framework/TestCaseFactory.h @@ -24,6 +24,7 @@ #ifndef ARM_COMPUTE_TEST_TEST_CASE_FACTORY #define ARM_COMPUTE_TEST_TEST_CASE_FACTORY +#include "DatasetModes.h" #include "TestCase.h" #include "support/ToolchainSupport.h" @@ -44,9 +45,10 @@ public: * * @param[in] suite_name Name of the test suite to which the test case has been added. * @param[in] name Name of the test case. + * @param[in] mode Datset mode of the test case. * @param[in] description Description of data arguments. */ - TestCaseFactory(std::string suite_name, std::string name, std::string description = ""); + TestCaseFactory(std::string suite_name, std::string name, DatasetMode mode, std::string description = ""); /** Default destructor. */ virtual ~TestCaseFactory() = default; @@ -57,6 +59,12 @@ public: */ std::string name() const; + /** Get the mode for which test case will be enabled. + * + * @return Dataset mode of the test case. + */ + DatasetMode mode() const; + /** Factory function to create the test case * * @return Unique pointer to a newly created test case. @@ -67,6 +75,7 @@ private: const std::string _suite_name; const std::string _test_name; const std::string _data_description; + const DatasetMode _mode{ DatasetMode::ALL }; }; /** Implementation of a test case factory to create non-data test cases. */ @@ -88,10 +97,11 @@ public: * * @param[in] suite_name Name of the test suite to which the test case has been added. * @param[in] test_name Name of the test case. + * @param[in] mode Mode in which the test case is enabled. * @param[in] description Description of data arguments. * @param[in] data Input data for the test case. */ - DataTestCaseFactory(std::string suite_name, std::string test_name, std::string description, const D &data); + DataTestCaseFactory(std::string suite_name, std::string test_name, DatasetMode mode, std::string description, const D &data); std::unique_ptr<TestCase> make() const override; @@ -99,8 +109,8 @@ private: D _data; }; -inline TestCaseFactory::TestCaseFactory(std::string suite_name, std::string test_name, std::string description) - : _suite_name{ std::move(suite_name) }, _test_name{ std::move(test_name) }, _data_description{ std::move(description) } +inline TestCaseFactory::TestCaseFactory(std::string suite_name, std::string test_name, DatasetMode mode, std::string description) + : _suite_name{ std::move(suite_name) }, _test_name{ std::move(test_name) }, _data_description{ std::move(description) }, _mode{ mode } { } @@ -116,6 +126,11 @@ inline std::string TestCaseFactory::name() const return name; } +inline DatasetMode TestCaseFactory::mode() const +{ + return _mode; +} + template <typename T> inline std::unique_ptr<TestCase> SimpleTestCaseFactory<T>::make() const { @@ -123,8 +138,8 @@ inline std::unique_ptr<TestCase> SimpleTestCaseFactory<T>::make() const } template <typename T, typename D> -inline DataTestCaseFactory<T, D>::DataTestCaseFactory(std::string suite_name, std::string test_name, std::string description, const D &data) - : TestCaseFactory{ std::move(suite_name), std::move(test_name), std::move(description) }, _data{ data } +inline DataTestCaseFactory<T, D>::DataTestCaseFactory(std::string suite_name, std::string test_name, DatasetMode mode, std::string description, const D &data) + : TestCaseFactory{ std::move(suite_name), std::move(test_name), mode, std::move(description) }, _data{ data } { } |