diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Globals.h | 6 | ||||
-rw-r--r-- | tests/ParametersLibrary.cpp | 41 | ||||
-rw-r--r-- | tests/ParametersLibrary.h | 76 | ||||
-rw-r--r-- | tests/Utils.h | 3 | ||||
-rw-r--r-- | tests/benchmark/fixtures/ActivationLayerFixture.h | 13 | ||||
-rw-r--r-- | tests/framework/Framework.cpp | 12 | ||||
-rw-r--r-- | tests/framework/Framework.h | 9 | ||||
-rw-r--r-- | tests/framework/instruments/Instruments.h | 9 | ||||
-rw-r--r-- | tests/framework/instruments/SchedulerTimer.cpp | 28 | ||||
-rw-r--r-- | tests/framework/instruments/SchedulerTimer.h | 27 | ||||
-rw-r--r-- | tests/instruments/Helpers.h | 86 | ||||
-rw-r--r-- | tests/main.cpp | 32 | ||||
-rw-r--r-- | tests/validation/CL/ActivationLayer.cpp | 1 | ||||
-rw-r--r-- | tests/validation/NEON/ActivationLayer.cpp | 6 | ||||
-rw-r--r-- | tests/validation/NEON/UNIT/RuntimeContext.cpp | 166 | ||||
-rw-r--r-- | tests/validation/fixtures/ActivationLayerFixture.h | 3 |
16 files changed, 502 insertions, 16 deletions
diff --git a/tests/Globals.h b/tests/Globals.h index c4c450c5fe..569b1a31c6 100644 --- a/tests/Globals.h +++ b/tests/Globals.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -25,6 +25,7 @@ #define __ARM_COMPUTE_TEST_GLOBALS_H__ #include "tests/AssetsLibrary.h" +#include "tests/ParametersLibrary.h" #include <memory> @@ -32,7 +33,8 @@ namespace arm_compute { namespace test { -extern std::unique_ptr<AssetsLibrary> library; +extern std::unique_ptr<AssetsLibrary> library; +extern std::unique_ptr<ParametersLibrary> parameters; } // namespace test } // namespace arm_compute #endif /* __ARM_COMPUTE_TEST_GLOBALS_H__ */ diff --git a/tests/ParametersLibrary.cpp b/tests/ParametersLibrary.cpp new file mode 100644 index 0000000000..16152c8482 --- /dev/null +++ b/tests/ParametersLibrary.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019 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 "tests/ParametersLibrary.h" + +namespace arm_compute +{ +namespace test +{ +void ParametersLibrary::set_cpu_ctx(std::unique_ptr<IRuntimeContext> cpu_ctx) +{ + _cpu_ctx = std::move(cpu_ctx); +} + +template <> +typename ContextType<Tensor>::type *ParametersLibrary::get_ctx<Tensor>() +{ + return _cpu_ctx.get(); +} +} // namespace test +} // namespace arm_compute diff --git a/tests/ParametersLibrary.h b/tests/ParametersLibrary.h new file mode 100644 index 0000000000..a99be46d3f --- /dev/null +++ b/tests/ParametersLibrary.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019 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_PARAMETERS_LIBRARY_H__ +#define __ARM_COMPUTE_TEST_PARAMETERS_LIBRARY_H__ + +#include "arm_compute/runtime/IRuntimeContext.h" +#include "arm_compute/runtime/Tensor.h" + +#include <memory> + +namespace arm_compute +{ +namespace test +{ +// Return type trait helper +template <class T> +struct ContextType +{ + using type = void; +}; +template <> +struct ContextType<Tensor> +{ + using type = IRuntimeContext; +}; + +/** Class that contains all the global parameters used by the tests */ +class ParametersLibrary final +{ +public: + /** Default constructor */ + ParametersLibrary() = default; + /** Set cpu context to be used by the tests + * + * @param[in] cpu_ctx CPU context to use + */ + void set_cpu_ctx(std::unique_ptr<IRuntimeContext> cpu_ctx); + /** Get context given a tensor type + * + * @tparam TensorType + * + * @return Pointer to the context + */ + template <typename TensorType> + typename ContextType<TensorType>::type *get_ctx() + { + return nullptr; + } + +private: + std::unique_ptr<IRuntimeContext> _cpu_ctx{ nullptr }; +}; +} // namespace test +} // namespace arm_compute +#endif //__ARM_COMPUTE_TEST_PARAMETERS_LIBRARY_H__ diff --git a/tests/Utils.h b/tests/Utils.h index f88b01dc40..f26507d1a0 100644 --- a/tests/Utils.h +++ b/tests/Utils.h @@ -54,6 +54,9 @@ #include <type_traits> #include <vector> +#include "arm_compute/runtime/CPP/CPPScheduler.h" +#include "arm_compute/runtime/RuntimeContext.h" + namespace arm_compute { #ifdef ARM_COMPUTE_CL diff --git a/tests/benchmark/fixtures/ActivationLayerFixture.h b/tests/benchmark/fixtures/ActivationLayerFixture.h index a82861f624..2ac10b2746 100644 --- a/tests/benchmark/fixtures/ActivationLayerFixture.h +++ b/tests/benchmark/fixtures/ActivationLayerFixture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -41,6 +41,11 @@ template <typename TensorType, typename Function, typename Accessor> class ActivationLayerFixture : public framework::Fixture { public: + ActivationLayerFixture() + : src(), dst(), act_layer(parameters->get_ctx<TensorType>()) + { + } + template <typename...> void setup(TensorShape shape, ActivationLayerInfo info, DataType data_type, int batches) { @@ -78,9 +83,9 @@ public: } private: - TensorType src{}; - TensorType dst{}; - Function act_layer{}; + TensorType src; + TensorType dst; + Function act_layer; }; } // namespace benchmark } // namespace test diff --git a/tests/framework/Framework.cpp b/tests/framework/Framework.cpp index cc7852906c..fbc2456047 100644 --- a/tests/framework/Framework.cpp +++ b/tests/framework/Framework.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -40,6 +40,8 @@ namespace test { namespace framework { +std::unique_ptr<InstrumentsInfo> instruments_info; + Framework::Framework() { _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMESTAMPS, ScaleFactor::NONE), Instrument::make_instrument<WallClockTimestamps, ScaleFactor::NONE>); @@ -83,6 +85,8 @@ Framework::Framework() _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_MEMORY_USAGE, ScaleFactor::SCALE_1M), Instrument::make_instrument<OpenCLMemoryUsage, ScaleFactor::SCALE_1M>); #endif /* ARM_COMPUTE_CL */ + + instruments_info = support::cpp14::make_unique<InstrumentsInfo>(); } std::set<InstrumentsDescription> Framework::available_instruments() const @@ -679,6 +683,12 @@ LogLevel Framework::log_level() const { return _log_level; } + +void Framework::set_instruments_info(InstrumentsInfo instr_info) +{ + ARM_COMPUTE_ERROR_ON(instruments_info == nullptr); + *instruments_info = instr_info; +} } // namespace framework } // namespace test } // namespace arm_compute diff --git a/tests/framework/Framework.h b/tests/framework/Framework.h index 65ffc0a818..c02416f9b5 100644 --- a/tests/framework/Framework.h +++ b/tests/framework/Framework.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -293,6 +293,13 @@ public: * @return The current logging level. */ LogLevel log_level() const; + /** Sets instruments info + * + * @note TODO(COMPMID-2638) : Remove once instruments are transferred outside the framework. + * + * @param[in] instr_info Instruments info to set + */ + void set_instruments_info(InstrumentsInfo instr_info); private: Framework(); diff --git a/tests/framework/instruments/Instruments.h b/tests/framework/instruments/Instruments.h index 370db8d4dc..8adf501c18 100644 --- a/tests/framework/instruments/Instruments.h +++ b/tests/framework/instruments/Instruments.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -33,6 +33,7 @@ #include "SchedulerTimer.h" #include "WallClockTimer.h" +#include <memory> #include <sstream> #include <string> @@ -59,6 +60,12 @@ enum class InstrumentType : unsigned int SCHEDULER_TIMESTAMPS = 0x0900, }; +struct InstrumentsInfo +{ + std::vector<ISchedulerUser *> _scheduler_users{}; +}; +extern std::unique_ptr<InstrumentsInfo> instruments_info; + using InstrumentsDescription = std::pair<InstrumentType, ScaleFactor>; InstrumentsDescription instrument_type_from_name(const std::string &name); diff --git a/tests/framework/instruments/SchedulerTimer.cpp b/tests/framework/instruments/SchedulerTimer.cpp index c114dfbd9d..98c9b878d9 100644 --- a/tests/framework/instruments/SchedulerTimer.cpp +++ b/tests/framework/instruments/SchedulerTimer.cpp @@ -23,6 +23,7 @@ */ #include "SchedulerTimer.h" +#include "Instruments.h" #include "WallClockTimer.h" #include "arm_compute/core/CPP/ICPPKernel.h" #include "arm_compute/core/utils/misc/Cast.h" @@ -114,8 +115,12 @@ private: template <bool output_timestamps> SchedulerClock<output_timestamps>::SchedulerClock(ScaleFactor scale_factor) - : _kernels(), _real_scheduler(nullptr), _real_scheduler_type(), _real_graph_function(nullptr), _scale_factor(scale_factor), _interceptor(nullptr) + : _kernels(), _real_scheduler(nullptr), _real_scheduler_type(), _real_graph_function(nullptr), _scale_factor(scale_factor), _interceptor(nullptr), _scheduler_users() { + if(instruments_info != nullptr) + { + _scheduler_users = instruments_info->_scheduler_users; + } } template <bool output_timestamps> @@ -157,6 +162,17 @@ void SchedulerClock<output_timestamps>::test_start() _interceptor = std::make_shared<Interceptor<output_timestamps>>(_kernels, *_real_scheduler, _scale_factor); Scheduler::set(std::static_pointer_cast<IScheduler>(_interceptor)); graph::TaskExecutor::get().execute_function = task_interceptor; + + // Create an interceptor for each scheduler + // TODO(COMPID-2638) : Allow multiple schedulers, now it assumes the same scheduler is used. + std::for_each(std::begin(_scheduler_users), std::end(_scheduler_users), + [&](ISchedulerUser * user) + { + if(user != nullptr && user->scheduler() != nullptr) + { + user->intercept_scheduler(support::cpp14::make_unique<Interceptor<output_timestamps>>(_kernels, *user->scheduler(), _scale_factor)); + } + }); } } @@ -175,6 +191,16 @@ void SchedulerClock<output_timestamps>::test_stop() _interceptor = nullptr; graph::TaskExecutor::get().execute_function = _real_graph_function; _real_graph_function = nullptr; + + // Restore schedulers + std::for_each(std::begin(_scheduler_users), std::end(_scheduler_users), + [&](ISchedulerUser * user) + { + if(user != nullptr) + { + user->restore_scheduler(); + } + }); } template <bool output_timestamps> diff --git a/tests/framework/instruments/SchedulerTimer.h b/tests/framework/instruments/SchedulerTimer.h index 64adb488ae..ea64b227eb 100644 --- a/tests/framework/instruments/SchedulerTimer.h +++ b/tests/framework/instruments/SchedulerTimer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -29,6 +29,8 @@ #include "arm_compute/runtime/Scheduler.h" #include <list> +#include <memory> +#include <vector> namespace arm_compute { @@ -36,6 +38,26 @@ namespace test { namespace framework { +/** Scheduler user interface */ +class ISchedulerUser +{ +public: + /** Default Destructor */ + virtual ~ISchedulerUser() = default; + /** Intercept the scheduler used by + * + * @param interceptor Intercept the scheduler used by the scheduler user. + */ + virtual void intercept_scheduler(std::unique_ptr<IScheduler> interceptor) = 0; + /** Restore the original scheduler */ + virtual void restore_scheduler() = 0; + /** Real scheduler accessor + * + * @return The real scheduler + */ + virtual IScheduler *scheduler() = 0; +}; + /** Instrument creating measurements based on the information returned by clGetEventProfilingInfo for each OpenCL kernel executed*/ template <bool output_timestamps> class SchedulerClock : public Instrument @@ -46,7 +68,6 @@ public: * @param[in] scale_factor Measurement scale factor. */ SchedulerClock(ScaleFactor scale_factor); - /** Prevent instances of this class from being copy constructed */ SchedulerClock(const SchedulerClock &) = delete; /** Prevent instances of this class from being copied */ @@ -58,6 +79,7 @@ public: /** Use the default destructor */ ~SchedulerClock() = default; + // Inherited overridden methods std::string id() const override; void test_start() override; void start() override; @@ -79,6 +101,7 @@ private: std::function<decltype(graph::execute_task)> _real_graph_function; ScaleFactor _scale_factor; std::shared_ptr<IScheduler> _interceptor; + std::vector<ISchedulerUser *> _scheduler_users; }; using SchedulerTimer = SchedulerClock<false>; diff --git a/tests/instruments/Helpers.h b/tests/instruments/Helpers.h new file mode 100644 index 0000000000..07387f10f8 --- /dev/null +++ b/tests/instruments/Helpers.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2019 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_INSTRUMENTS_UTILS_H__ +#define __ARM_COMPUTE_TEST_INSTRUMENTS_UTILS_H__ + +#include "arm_compute/runtime/RuntimeContext.h" +#include "tests/framework/instruments/Instruments.h" + +namespace arm_compute +{ +namespace test +{ +class ContextSchedulerUser : public framework::ISchedulerUser +{ +public: + /** Default Constructor + * + * @param[in] ctx Runtime context to track + */ + ContextSchedulerUser(RuntimeContext *ctx) + : _ctx(ctx), _scheduler_to_use(nullptr), _real_scheduler(nullptr), _interceptor(nullptr) + { + ARM_COMPUTE_ERROR_ON(ctx == nullptr); + _real_scheduler = _ctx->scheduler(); + _scheduler_to_use = _real_scheduler; + } + /** Prevent instances of this class from being copied (As this class contains pointers) */ + ContextSchedulerUser(const ContextSchedulerUser &) = delete; + /** Default move constructor */ + ContextSchedulerUser(ContextSchedulerUser &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + ContextSchedulerUser &operator=(const ContextSchedulerUser &) = delete; + /** Default move assignment operator */ + ContextSchedulerUser &operator=(ContextSchedulerUser &&) = default; + + // Overridden inherited methods + void intercept_scheduler(std::unique_ptr<IScheduler> interceptor) + { + if(interceptor != nullptr) + { + _interceptor = std::move(interceptor); + _scheduler_to_use = _interceptor.get(); + _ctx->set_scheduler(_scheduler_to_use); + } + } + void restore_scheduler() + { + _interceptor = nullptr; + _scheduler_to_use = _real_scheduler; + _ctx->set_scheduler(_scheduler_to_use); + } + IScheduler *scheduler() + { + return _real_scheduler; + } + +private: + RuntimeContext *_ctx; + IScheduler *_scheduler_to_use; + IScheduler *_real_scheduler; + std::unique_ptr<IScheduler> _interceptor; +}; +} // namespace test +} // namespace arm_compute +#endif /* __ARM_COMPUTE_TEST_INSTRUMENTS_UTILS_H__ */ diff --git a/tests/main.cpp b/tests/main.cpp index 9690eb9a00..01741939a0 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -23,6 +23,7 @@ */ #include "support/ToolchainSupport.h" #include "tests/AssetsLibrary.h" +#include "tests/ParametersLibrary.h" #include "tests/framework/DatasetModes.h" #include "tests/framework/Exceptions.h" #include "tests/framework/Framework.h" @@ -31,6 +32,7 @@ #include "tests/framework/command_line/CommonOptions.h" #include "tests/framework/instruments/Instruments.h" #include "tests/framework/printers/Printers.h" +#include "tests/instruments/Helpers.h" #include "utils/command_line/CommandLineOptions.h" #include "utils/command_line/CommandLineParser.h" @@ -72,7 +74,8 @@ namespace arm_compute { namespace test { -std::unique_ptr<AssetsLibrary> library; +std::unique_ptr<AssetsLibrary> library; +std::unique_ptr<ParametersLibrary> parameters; } // namespace test } // namespace arm_compute @@ -167,7 +170,20 @@ int main(int argc, char **argv) std::vector<std::unique_ptr<framework::Printer>> printers = options.create_printers(); + // Setup CPU Scheduler Scheduler::get().set_num_threads(threads->value()); + + // Create CPU context + auto cpu_ctx = support::cpp14::make_unique<RuntimeContext>(); + cpu_ctx->set_scheduler(&Scheduler::get()); + + // Track CPU context + auto cpu_ctx_track = support::cpp14::make_unique<ContextSchedulerUser>(cpu_ctx.get()); + + // Create parameters + parameters = support::cpp14::make_unique<ParametersLibrary>(); + parameters->set_cpu_ctx(std::move(cpu_ctx)); + #ifdef ARM_COMPUTE_CL if(enable_tuner->is_set()) { @@ -232,7 +248,19 @@ int main(int argc, char **argv) } } - framework.init(options.instruments->value(), options.iterations->value(), dataset_mode->value(), filter->value(), filter_id->value(), options.log_level->value()); + // Setup instruments meta-data + framework::InstrumentsInfo instruments_info; + instruments_info._scheduler_users.push_back(cpu_ctx_track.get()); + framework.set_instruments_info(instruments_info); + + // Initialize framework + framework.init(options.instruments->value(), + options.iterations->value(), + dataset_mode->value(), + filter->value(), + filter_id->value(), + options.log_level->value()); + for(auto &p : printers) { framework.add_printer(p.get()); diff --git a/tests/validation/CL/ActivationLayer.cpp b/tests/validation/CL/ActivationLayer.cpp index e97f12f5a3..250777d541 100644 --- a/tests/validation/CL/ActivationLayer.cpp +++ b/tests/validation/CL/ActivationLayer.cpp @@ -25,6 +25,7 @@ #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/CL/CLTensorAllocator.h" #include "arm_compute/runtime/CL/functions/CLActivationLayer.h" +#include "arm_compute/runtime/RuntimeContext.h" #include "tests/CL/CLAccessor.h" #include "tests/PaddingCalculator.h" #include "tests/datasets/ActivationFunctionsDataset.h" diff --git a/tests/validation/NEON/ActivationLayer.cpp b/tests/validation/NEON/ActivationLayer.cpp index eb3a37fba7..8c18d47da9 100644 --- a/tests/validation/NEON/ActivationLayer.cpp +++ b/tests/validation/NEON/ActivationLayer.cpp @@ -23,6 +23,7 @@ */ #include "arm_compute/core/Types.h" #include "arm_compute/runtime/NEON/functions/NEActivationLayer.h" +#include "arm_compute/runtime/RuntimeContext.h" #include "arm_compute/runtime/Tensor.h" #include "arm_compute/runtime/TensorAllocator.h" #include "tests/NEON/Accessor.h" @@ -133,8 +134,11 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(datas ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); + // Create context + RuntimeContext ctx; + // Create and configure function - NEActivationLayer act_layer; + NEActivationLayer act_layer(&ctx); if(in_place) { diff --git a/tests/validation/NEON/UNIT/RuntimeContext.cpp b/tests/validation/NEON/UNIT/RuntimeContext.cpp new file mode 100644 index 0000000000..05670a94e8 --- /dev/null +++ b/tests/validation/NEON/UNIT/RuntimeContext.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2019 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 "arm_compute/runtime/RuntimeContext.h" + +#include "arm_compute/runtime/CPP/CPPScheduler.h" +#include "arm_compute/runtime/NEON/functions/NEActivationLayer.h" +#include "arm_compute/runtime/Tensor.h" +#include "support/ToolchainSupport.h" +#include "tests/Globals.h" +#include "tests/NEON/Accessor.h" +#include "tests/Utils.h" +#include "tests/framework/Asserts.h" +#include "tests/framework/Macros.h" +#include "tests/validation/Validation.h" +#include "tests/validation/reference/ActivationLayer.h" + +#include <memory> +#include <random> +#if !defined(BARE_METAL) +#include <thread> +#endif // !defined(BARE_METAL) + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +TEST_SUITE(NEON) +TEST_SUITE(UNIT) +TEST_SUITE(RuntimeContext) + +TEST_CASE(Scheduler, framework::DatasetMode::ALL) +{ + using namespace arm_compute; + // Create a runtime context object + RuntimeContext ctx; + + // Check if it's been initialised properly + ARM_COMPUTE_EXPECT(ctx.scheduler() != nullptr, framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT(ctx.asset_manager() == nullptr, framework::LogLevel::ERRORS); + + // Create a CPPScheduler + CPPScheduler scheduler; + ctx.set_scheduler(&scheduler); + // Check if the scheduler has been properly setup + ARM_COMPUTE_EXPECT(ctx.scheduler() != nullptr, framework::LogLevel::ERRORS); + + // Create a new activation function + NEActivationLayer act_layer(&ctx); + + Tensor src = create_tensor<Tensor>(TensorShape(32, 32), DataType::F32, 1); + Tensor dst = create_tensor<Tensor>(TensorShape(32, 32), DataType::F32, 1); + + act_layer.configure(&src, &dst, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LINEAR)); + + ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); + + // Allocate tensors + src.allocator()->allocate(); + dst.allocator()->allocate(); + + ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS); + + float min_bound = 0; + float max_bound = 0; + std::tie(min_bound, max_bound) = get_activation_layer_test_bounds<float>(ActivationLayerInfo::ActivationFunction::LINEAR, DataType::F32); + std::uniform_real_distribution<> distribution(min_bound, max_bound); + library->fill(Accessor(src), distribution, 0); + + // Compute function + act_layer.run(); +} + +#if !defined(BARE_METAL) +// This test tries scheduling work concurrently from two independent threads +TEST_CASE(MultipleThreadedScheduller, framework::DatasetMode::ALL) +{ + // Create a runtime context object for thread 1 + RuntimeContext ctx1; + + // Create a runtime context object for thread 2 + RuntimeContext ctx2; + + // Create a new activation function + NEActivationLayer act_layer_thread0(&ctx1); + NEActivationLayer act_layer_thread1(&ctx2); + + const TensorShape tensor_shape(128, 128); + Tensor src_t0 = create_tensor<Tensor>(tensor_shape, DataType::F32, 1); + Tensor dst_t0 = create_tensor<Tensor>(tensor_shape, DataType::F32, 1); + Tensor src_t1 = create_tensor<Tensor>(tensor_shape, DataType::F32, 1); + Tensor dst_t1 = create_tensor<Tensor>(tensor_shape, DataType::F32, 1); + ActivationLayerInfo activation_info(ActivationLayerInfo::ActivationFunction::LINEAR); + + act_layer_thread0.configure(&src_t0, &dst_t0, activation_info); + act_layer_thread1.configure(&src_t1, &dst_t1, activation_info); + + ARM_COMPUTE_EXPECT(src_t0.info()->is_resizable(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT(dst_t0.info()->is_resizable(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT(src_t1.info()->is_resizable(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT(dst_t1.info()->is_resizable(), framework::LogLevel::ERRORS); + + // Allocate tensors + src_t0.allocator()->allocate(); + dst_t0.allocator()->allocate(); + src_t1.allocator()->allocate(); + dst_t1.allocator()->allocate(); + + ARM_COMPUTE_EXPECT(!src_t0.info()->is_resizable(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT(!src_t1.info()->is_resizable(), framework::LogLevel::ERRORS); + + float min_bound = 0; + float max_bound = 0; + std::tie(min_bound, max_bound) = get_activation_layer_test_bounds<float>(ActivationLayerInfo::ActivationFunction::LINEAR, DataType::F32); + std::uniform_real_distribution<> distribution(min_bound, max_bound); + library->fill(Accessor(src_t0), distribution, 0); + library->fill(Accessor(src_t1), distribution, 0); + + std::thread neon_thread1([&] { act_layer_thread0.run(); }); + std::thread neon_thread2([&] { act_layer_thread1.run(); }); + + neon_thread1.join(); + neon_thread2.join(); + + Window window; + window.use_tensor_dimensions(dst_t0.info()->tensor_shape()); + Iterator t0_it(&dst_t0, window); + Iterator t1_it(&dst_t1, window); + execute_window_loop(window, [&](const Coordinates &) + { + const bool match = (*reinterpret_cast<float *>(t0_it.ptr()) == *reinterpret_cast<float *>(t1_it.ptr())); + ARM_COMPUTE_EXPECT(match, framework::LogLevel::ERRORS); + }, + t0_it, t1_it); +} +#endif // !defined(BARE_METAL) + +TEST_SUITE_END() // RuntimeContext +TEST_SUITE_END() // UNIT +TEST_SUITE_END() // NEON +} // namespace validation +} // namespace test +} // namespace arm_compute diff --git a/tests/validation/fixtures/ActivationLayerFixture.h b/tests/validation/fixtures/ActivationLayerFixture.h index d9f26b7368..8fa74979a8 100644 --- a/tests/validation/fixtures/ActivationLayerFixture.h +++ b/tests/validation/fixtures/ActivationLayerFixture.h @@ -29,6 +29,7 @@ #include "tests/AssetsLibrary.h" #include "tests/Globals.h" #include "tests/IAccessor.h" +#include "tests/ParametersLibrary.h" #include "tests/framework/Asserts.h" #include "tests/framework/Fixture.h" #include "tests/validation/Helpers.h" @@ -94,7 +95,7 @@ protected: TensorType dst = create_tensor<TensorType>(shape, _data_type, 1, _output_quantization_info); // Create and configure function - FunctionType act_layer; + FunctionType act_layer(parameters->get_ctx<TensorType>()); TensorType *dst_ptr = _in_place ? nullptr : &dst; |