aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorgios Pinitas <georgios.pinitas@arm.com>2019-07-25 13:31:10 +0100
committerGeorgios Pinitas <georgios.pinitas@arm.com>2019-09-09 11:22:01 +0000
commit12833d063259cb7809a97a4262f821efdc40554f (patch)
tree455333091c9eeba97079a385e0186f56076f5169 /src
parented0e35bfe15bad01387504afc15b8553e585bdb9 (diff)
downloadComputeLibrary-12833d063259cb7809a97a4262f821efdc40554f.tar.gz
COMPMID-2204: RuntimeContext interface for NEON functions.
This patch creates the interfaces for the runtime context for NEON. Only the Neon backend implements the context which currently only holds an instance of the scheduler. The NEActivationLayer function has been updated to use the new context interface and the corresponding validation tests ported. Change-Id: I32e7e6aa888796dcbbfc5039b1e7f784a24f47da Signed-off-by: Pablo Tello <pablo.tello@arm.com> Reviewed-on: https://review.mlplatform.org/c/1851 Comments-Addressed: Arm Jenkins <bsgcomp@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com> Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/CL/functions/CLActivationLayer.cpp10
-rw-r--r--src/runtime/CPP/CPPScheduler.cpp62
-rw-r--r--src/runtime/CPP/SingleThreadScheduler.cpp8
-rw-r--r--src/runtime/DeviceProperties.cpp34
-rw-r--r--src/runtime/GLES_COMPUTE/functions/GCActivationLayer.cpp10
-rw-r--r--src/runtime/NEON/INESimpleFunctionNoBorder.cpp10
-rw-r--r--src/runtime/NEON/functions/NEActivationLayer.cpp12
-rw-r--r--src/runtime/OMP/OMPScheduler.cpp11
-rw-r--r--src/runtime/RuntimeContext.cpp56
-rw-r--r--src/runtime/Scheduler.cpp107
-rw-r--r--src/runtime/SchedulerFactory.cpp82
-rw-r--r--src/runtime/Utils.cpp26
12 files changed, 316 insertions, 112 deletions
diff --git a/src/runtime/CL/functions/CLActivationLayer.cpp b/src/runtime/CL/functions/CLActivationLayer.cpp
index 4aeb3a15e1..2b66795cf9 100644
--- a/src/runtime/CL/functions/CLActivationLayer.cpp
+++ b/src/runtime/CL/functions/CLActivationLayer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018 ARM Limited.
+ * Copyright (c) 2016-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -27,7 +27,12 @@
#include "arm_compute/core/Types.h"
#include "support/ToolchainSupport.h"
-using namespace arm_compute;
+namespace arm_compute
+{
+CLActivationLayer::CLActivationLayer(void *ctx)
+{
+ ARM_COMPUTE_UNUSED(ctx);
+}
void CLActivationLayer::configure(ICLTensor *input, ICLTensor *output, ActivationLayerInfo act_info)
{
@@ -40,3 +45,4 @@ Status CLActivationLayer::validate(const ITensorInfo *input, const ITensorInfo *
{
return CLActivationLayerKernel::validate(input, output, act_info);
}
+} // namespace arm_compute
diff --git a/src/runtime/CPP/CPPScheduler.cpp b/src/runtime/CPP/CPPScheduler.cpp
index 5916bb46fd..9b670d5c04 100644
--- a/src/runtime/CPP/CPPScheduler.cpp
+++ b/src/runtime/CPP/CPPScheduler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018 ARM Limited.
+ * Copyright (c) 2016-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -32,6 +32,7 @@
#include <atomic>
#include <condition_variable>
#include <iostream>
+#include <list>
#include <mutex>
#include <system_error>
#include <thread>
@@ -90,7 +91,31 @@ void process_workloads(std::vector<IScheduler::Workload> &workloads, ThreadFeede
} //namespace
-class CPPScheduler::Thread
+struct CPPScheduler::Impl
+{
+ Impl(unsigned int thread_hint)
+ : _num_threads(thread_hint), _threads(_num_threads - 1)
+ {
+ }
+ void set_num_threads(unsigned int num_threads, unsigned int thead_hint)
+ {
+ _num_threads = num_threads == 0 ? thead_hint : num_threads;
+ _threads.resize(_num_threads - 1);
+ }
+ unsigned int num_threads() const
+ {
+ return _num_threads;
+ }
+
+ void run_workloads(std::vector<IScheduler::Workload> &workloads);
+
+ class Thread;
+
+ unsigned int _num_threads;
+ std::list<Thread> _threads;
+};
+
+class CPPScheduler::Impl::Thread
{
public:
/** Start a new thread. */
@@ -132,12 +157,12 @@ private:
std::exception_ptr _current_exception{ nullptr };
};
-CPPScheduler::Thread::Thread()
+CPPScheduler::Impl::Thread::Thread()
{
_thread = std::thread(&Thread::worker_thread, this);
}
-CPPScheduler::Thread::~Thread()
+CPPScheduler::Impl::Thread::~Thread()
{
// Make sure worker thread has ended
if(_thread.joinable())
@@ -148,7 +173,7 @@ CPPScheduler::Thread::~Thread()
}
}
-void CPPScheduler::Thread::start(std::vector<IScheduler::Workload> *workloads, ThreadFeeder &feeder, const ThreadInfo &info)
+void CPPScheduler::Impl::Thread::start(std::vector<IScheduler::Workload> *workloads, ThreadFeeder &feeder, const ThreadInfo &info)
{
_workloads = workloads;
_feeder = &feeder;
@@ -161,7 +186,7 @@ void CPPScheduler::Thread::start(std::vector<IScheduler::Workload> *workloads, T
_cv.notify_one();
}
-void CPPScheduler::Thread::wait()
+void CPPScheduler::Impl::Thread::wait()
{
{
std::unique_lock<std::mutex> lock(_m);
@@ -174,7 +199,7 @@ void CPPScheduler::Thread::wait()
}
}
-void CPPScheduler::Thread::worker_thread()
+void CPPScheduler::Impl::Thread::worker_thread()
{
while(true)
{
@@ -209,6 +234,9 @@ void CPPScheduler::Thread::worker_thread()
}
}
+/*
+ * This singleton has been deprecated and will be removed in the next release
+ */
CPPScheduler &CPPScheduler::get()
{
static CPPScheduler scheduler;
@@ -216,26 +244,26 @@ CPPScheduler &CPPScheduler::get()
}
CPPScheduler::CPPScheduler()
- : _num_threads(num_threads_hint()),
- _threads(_num_threads - 1)
+ : _impl(support::cpp14::make_unique<Impl>(num_threads_hint()))
{
}
+CPPScheduler::~CPPScheduler() = default;
+
void CPPScheduler::set_num_threads(unsigned int num_threads)
{
- _num_threads = num_threads == 0 ? num_threads_hint() : num_threads;
- _threads.resize(_num_threads - 1);
+ _impl->set_num_threads(num_threads, num_threads_hint());
}
unsigned int CPPScheduler::num_threads() const
{
- return _num_threads;
+ return _impl->num_threads();
}
#ifndef DOXYGEN_SKIP_THIS
void CPPScheduler::run_workloads(std::vector<IScheduler::Workload> &workloads)
{
- const unsigned int num_threads = std::min(_num_threads, static_cast<unsigned int>(workloads.size()));
+ const unsigned int num_threads = std::min(_impl->num_threads(), static_cast<unsigned int>(workloads.size()));
if(num_threads < 1)
{
return;
@@ -245,7 +273,7 @@ void CPPScheduler::run_workloads(std::vector<IScheduler::Workload> &workloads)
info.cpu_info = &_cpu_info;
info.num_threads = num_threads;
unsigned int t = 0;
- auto thread_it = _threads.begin();
+ auto thread_it = _impl->_threads.begin();
for(; t < num_threads - 1; ++t, ++thread_it)
{
info.thread_id = t;
@@ -258,7 +286,7 @@ void CPPScheduler::run_workloads(std::vector<IScheduler::Workload> &workloads)
try
{
#endif /* ARM_COMPUTE_EXCEPTIONS_DISABLED */
- for(auto &thread : _threads)
+ for(auto &thread : _impl->_threads)
{
thread.wait();
}
@@ -278,7 +306,7 @@ void CPPScheduler::schedule(ICPPKernel *kernel, const Hints &hints)
const Window &max_window = kernel->window();
const unsigned int num_iterations = max_window.num_iterations(hints.split_dimension());
- const unsigned int num_threads = std::min(num_iterations, _num_threads);
+ const unsigned int num_threads = std::min(num_iterations, _impl->_num_threads);
if(num_iterations == 0)
{
@@ -302,7 +330,7 @@ void CPPScheduler::schedule(ICPPKernel *kernel, const Hints &hints)
case StrategyHint::DYNAMIC:
{
// Make sure we don't use some windows which are too small as this might create some contention on the ThreadFeeder
- const unsigned int max_iterations = static_cast<unsigned int>(_num_threads) * 3;
+ const unsigned int max_iterations = static_cast<unsigned int>(_impl->_num_threads) * 3;
num_windows = num_iterations > max_iterations ? max_iterations : num_iterations;
break;
}
diff --git a/src/runtime/CPP/SingleThreadScheduler.cpp b/src/runtime/CPP/SingleThreadScheduler.cpp
index 37011595fd..152569fb67 100644
--- a/src/runtime/CPP/SingleThreadScheduler.cpp
+++ b/src/runtime/CPP/SingleThreadScheduler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -29,12 +29,6 @@
namespace arm_compute
{
-SingleThreadScheduler &SingleThreadScheduler::get()
-{
- static SingleThreadScheduler scheduler;
- return scheduler;
-}
-
void SingleThreadScheduler::set_num_threads(unsigned int num_threads)
{
ARM_COMPUTE_UNUSED(num_threads);
diff --git a/src/runtime/DeviceProperties.cpp b/src/runtime/DeviceProperties.cpp
new file mode 100644
index 0000000000..e88aa7124c
--- /dev/null
+++ b/src/runtime/DeviceProperties.cpp
@@ -0,0 +1,34 @@
+/*
+ * 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/DeviceProperties.h"
+
+#include "arm_compute/runtime/CPUUtils.h"
+
+namespace arm_compute
+{
+DeviceProperties::DeviceProperties()
+{
+ get_cpu_configuration(cpu_info);
+}
+} // namespace arm_compute
diff --git a/src/runtime/GLES_COMPUTE/functions/GCActivationLayer.cpp b/src/runtime/GLES_COMPUTE/functions/GCActivationLayer.cpp
index 8686416616..207e8cef56 100644
--- a/src/runtime/GLES_COMPUTE/functions/GCActivationLayer.cpp
+++ b/src/runtime/GLES_COMPUTE/functions/GCActivationLayer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -27,7 +27,12 @@
#include "arm_compute/core/Helpers.h"
#include "support/ToolchainSupport.h"
-using namespace arm_compute;
+namespace arm_compute
+{
+GCActivationLayer::GCActivationLayer(void *ctx)
+{
+ ARM_COMPUTE_UNUSED(ctx);
+}
void GCActivationLayer::configure(IGCTensor *input, IGCTensor *output, ActivationLayerInfo act_info)
{
@@ -35,3 +40,4 @@ void GCActivationLayer::configure(IGCTensor *input, IGCTensor *output, Activatio
k->configure(input, output, act_info);
_kernel = std::move(k);
}
+} // namespace arm_compute
diff --git a/src/runtime/NEON/INESimpleFunctionNoBorder.cpp b/src/runtime/NEON/INESimpleFunctionNoBorder.cpp
index 12872048c7..2cabee4c46 100644
--- a/src/runtime/NEON/INESimpleFunctionNoBorder.cpp
+++ b/src/runtime/NEON/INESimpleFunctionNoBorder.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 ARM Limited.
+ * Copyright (c) 2018-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -24,16 +24,18 @@
#include "arm_compute/runtime/NEON/INESimpleFunctionNoBorder.h"
#include "arm_compute/runtime/NEON/NEScheduler.h"
+#include "arm_compute/runtime/Utils.h"
namespace arm_compute
{
-INESimpleFunctionNoBorder::INESimpleFunctionNoBorder() // NOLINT
- : _kernel()
+INESimpleFunctionNoBorder::INESimpleFunctionNoBorder(IRuntimeContext *ctx)
+ : _kernel(),
+ _ctx(ctx)
{
}
void INESimpleFunctionNoBorder::run()
{
- NEScheduler::get().schedule(_kernel.get(), Window::DimY);
+ schedule_kernel_on_ctx(_ctx, _kernel.get(), Window::DimY);
}
} // namespace arm_compute
diff --git a/src/runtime/NEON/functions/NEActivationLayer.cpp b/src/runtime/NEON/functions/NEActivationLayer.cpp
index 6af71a3580..1b8651487d 100644
--- a/src/runtime/NEON/functions/NEActivationLayer.cpp
+++ b/src/runtime/NEON/functions/NEActivationLayer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -24,10 +24,15 @@
#include "arm_compute/runtime/NEON/functions/NEActivationLayer.h"
#include "arm_compute/core/NEON/kernels/NEActivationLayerKernel.h"
+#include "arm_compute/runtime/IRuntimeContext.h"
#include "support/ToolchainSupport.h"
-using namespace arm_compute;
-
+namespace arm_compute
+{
+NEActivationLayer::NEActivationLayer(IRuntimeContext *ctx) // NOLINT
+ : INESimpleFunctionNoBorder(ctx)
+{
+}
void NEActivationLayer::configure(ITensor *input, ITensor *output, ActivationLayerInfo activation_info)
{
auto k = arm_compute::support::cpp14::make_unique<NEActivationLayerKernel>();
@@ -39,3 +44,4 @@ Status NEActivationLayer::validate(const ITensorInfo *input, const ITensorInfo *
{
return NEActivationLayerKernel::validate(input, output, act_info);
}
+} // namespace arm_compute
diff --git a/src/runtime/OMP/OMPScheduler.cpp b/src/runtime/OMP/OMPScheduler.cpp
index 2355389dbd..f67f06fc94 100644
--- a/src/runtime/OMP/OMPScheduler.cpp
+++ b/src/runtime/OMP/OMPScheduler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -31,14 +31,8 @@
#include <omp.h>
-using namespace arm_compute;
-
-OMPScheduler &OMPScheduler::get()
+namespace arm_compute
{
- static OMPScheduler scheduler;
- return scheduler;
-}
-
OMPScheduler::OMPScheduler() // NOLINT
: _num_threads(omp_get_max_threads())
{
@@ -109,3 +103,4 @@ void OMPScheduler::run_workloads(std::vector<arm_compute::IScheduler::Workload>
}
}
#endif /* DOXYGEN_SKIP_THIS */
+} // namespace arm_compute
diff --git a/src/runtime/RuntimeContext.cpp b/src/runtime/RuntimeContext.cpp
new file mode 100644
index 0000000000..308e2788a9
--- /dev/null
+++ b/src/runtime/RuntimeContext.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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/core/Validate.h"
+#include "arm_compute/runtime/SchedulerFactory.h"
+
+namespace arm_compute
+{
+RuntimeContext::RuntimeContext()
+ : _owned_scheduler(SchedulerFactory::create()), _scheduler(_owned_scheduler.get()), _device_props()
+{
+}
+
+void RuntimeContext::set_scheduler(IScheduler *scheduler)
+{
+ ARM_COMPUTE_ERROR_ON_NULLPTR(scheduler);
+ _scheduler = scheduler;
+}
+
+IScheduler *RuntimeContext::scheduler()
+{
+ return _scheduler;
+}
+
+IAssetManager *RuntimeContext::asset_manager()
+{
+ return nullptr;
+}
+
+const DeviceProperties &RuntimeContext::properties()
+{
+ return _device_props;
+}
+} // namespace arm_compute
diff --git a/src/runtime/Scheduler.cpp b/src/runtime/Scheduler.cpp
index 8925acfa47..1af39d8122 100644
--- a/src/runtime/Scheduler.cpp
+++ b/src/runtime/Scheduler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -24,6 +24,8 @@
#include "arm_compute/runtime/Scheduler.h"
#include "arm_compute/core/Error.h"
+#include "support/ToolchainSupport.h"
+
#if ARM_COMPUTE_CPP_SCHEDULER
#include "arm_compute/runtime/CPP/CPPScheduler.h"
#endif /* ARM_COMPUTE_CPP_SCHEDULER */
@@ -46,6 +48,27 @@ Scheduler::Type Scheduler::_scheduler_type = Scheduler::Type::CPP;
Scheduler::Type Scheduler::_scheduler_type = Scheduler::Type::ST;
#endif /* ARM_COMPUTE_*_SCHEDULER */
+std::shared_ptr<IScheduler> Scheduler::_custom_scheduler = nullptr;
+
+namespace
+{
+std::map<Scheduler::Type, std::unique_ptr<IScheduler>> init()
+{
+ std::map<Scheduler::Type, std::unique_ptr<IScheduler>> m;
+ m[Scheduler::Type::ST] = support::cpp14::make_unique<SingleThreadScheduler>();
+#if defined(ARM_COMPUTE_CPP_SCHEDULER)
+ m[Scheduler::Type::CPP] = support::cpp14::make_unique<CPPScheduler>();
+#endif // defined(ARM_COMPUTE_CPP_SCHEDULER)
+#if defined(ARM_COMPUTE_OPENMP_SCHEDULER)
+ m[Scheduler::Type::OMP] = support::cpp14::make_unique<OMPScheduler>();
+#endif // defined(ARM_COMPUTE_OPENMP_SCHEDULER)
+
+ return m;
+}
+} // namespace
+
+std::map<Scheduler::Type, std::unique_ptr<IScheduler>> Scheduler::_schedulers = init();
+
void Scheduler::set(Type t)
{
ARM_COMPUTE_ERROR_ON(!Scheduler::is_available(t));
@@ -54,37 +77,13 @@ void Scheduler::set(Type t)
bool Scheduler::is_available(Type t)
{
- switch(t)
+ if(t == Type::CUSTOM)
{
- case Type::ST:
- {
- return true;
- }
- case Type::CPP:
- {
-#if ARM_COMPUTE_CPP_SCHEDULER
- return true;
-#else /* ARM_COMPUTE_CPP_SCHEDULER */
- return false;
-#endif /* ARM_COMPUTE_CPP_SCHEDULER */
- }
- case Type::OMP:
- {
-#if ARM_COMPUTE_OPENMP_SCHEDULER
- return true;
-#else /* ARM_COMPUTE_OPENMP_SCHEDULER */
- return false;
-#endif /* ARM_COMPUTE_OPENMP_SCHEDULER */
- }
- case Type::CUSTOM:
- {
- return _custom_scheduler != nullptr;
- }
- default:
- {
- ARM_COMPUTE_ERROR("Invalid Scheduler type");
- return false;
- }
+ return _custom_scheduler != nullptr;
+ }
+ else
+ {
+ return _schedulers.find(t) != _schedulers.end();
}
}
@@ -95,53 +94,31 @@ Scheduler::Type Scheduler::get_type()
IScheduler &Scheduler::get()
{
- switch(_scheduler_type)
+ if(_scheduler_type == Type::CUSTOM)
{
- case Type::ST:
- {
- return SingleThreadScheduler::get();
- }
- case Type::CPP:
+ if(_custom_scheduler == nullptr)
{
-#if ARM_COMPUTE_CPP_SCHEDULER
- return CPPScheduler::get();
-#else /* ARM_COMPUTE_CPP_SCHEDULER */
- ARM_COMPUTE_ERROR("Recompile with cppthreads=1 to use C++11 scheduler.");
-#endif /* ARM_COMPUTE_CPP_SCHEDULER */
- break;
+ ARM_COMPUTE_ERROR("No custom scheduler has been setup. Call set(std::shared_ptr<IScheduler> &scheduler) before Scheduler::get()");
}
- case Type::OMP:
+ else
{
-#if ARM_COMPUTE_OPENMP_SCHEDULER
- return OMPScheduler::get();
-#else /* ARM_COMPUTE_OPENMP_SCHEDULER */
- ARM_COMPUTE_ERROR("Recompile with openmp=1 to use openmp scheduler.");
-#endif /* ARM_COMPUTE_OPENMP_SCHEDULER */
- break;
+ return *_custom_scheduler;
}
- case Type::CUSTOM:
+ }
+ else
+ {
+ auto it = _schedulers.find(_scheduler_type);
+ if(it != _schedulers.end())
{
- if(_custom_scheduler == nullptr)
- {
- ARM_COMPUTE_ERROR("No custom scheduler has been setup. Call set(std::shared_ptr<IScheduler> &scheduler) before Scheduler::get()");
- }
- else
- {
- return *_custom_scheduler;
- }
- break;
+ return *it->second;
}
- default:
+ else
{
ARM_COMPUTE_ERROR("Invalid Scheduler type");
- break;
}
}
- return SingleThreadScheduler::get();
}
-std::shared_ptr<IScheduler> Scheduler::_custom_scheduler = nullptr;
-
void Scheduler::set(std::shared_ptr<IScheduler> scheduler)
{
_custom_scheduler = std::move(scheduler);
diff --git a/src/runtime/SchedulerFactory.cpp b/src/runtime/SchedulerFactory.cpp
new file mode 100644
index 0000000000..8bdd510367
--- /dev/null
+++ b/src/runtime/SchedulerFactory.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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/SchedulerFactory.h"
+
+#include "support/ToolchainSupport.h"
+
+#include "arm_compute/core/Error.h"
+#if ARM_COMPUTE_CPP_SCHEDULER
+#include "arm_compute/runtime/CPP/CPPScheduler.h"
+#endif /* ARM_COMPUTE_CPP_SCHEDULER */
+
+#include "arm_compute/runtime/SingleThreadScheduler.h"
+
+#if ARM_COMPUTE_OPENMP_SCHEDULER
+#include "arm_compute/runtime/OMP/OMPScheduler.h"
+#endif /* ARM_COMPUTE_OPENMP_SCHEDULER */
+
+namespace arm_compute
+{
+#if !ARM_COMPUTE_CPP_SCHEDULER && ARM_COMPUTE_OPENMP_SCHEDULER
+const SchedulerFactory::Type SchedulerFactory::_default_type = SchedulerFactory::Type::OMP;
+#elif ARM_COMPUTE_CPP_SCHEDULER && !ARM_COMPUTE_OPENMP_SCHEDULER
+const SchedulerFactory::Type SchedulerFactory::_default_type = SchedulerFactory::Type::CPP;
+#elif ARM_COMPUTE_CPP_SCHEDULER && ARM_COMPUTE_OPENMP_SCHEDULER
+const SchedulerFactory::Type SchedulerFactory::_default_type = SchedulerFactory::Type::CPP;
+#else /* ARM_COMPUTE_*_SCHEDULER */
+const SchedulerFactory::Type SchedulerFactory::_default_type = SchedulerFactory::Type::ST;
+#endif /* ARM_COMPUTE_*_SCHEDULER */
+
+std::unique_ptr<IScheduler> SchedulerFactory::create(Type type)
+{
+ switch(type)
+ {
+ case Type::ST:
+ {
+ return support::cpp14::make_unique<SingleThreadScheduler>();
+ }
+ case Type::CPP:
+ {
+#if ARM_COMPUTE_CPP_SCHEDULER
+ return support::cpp14::make_unique<CPPScheduler>();
+#else /* ARM_COMPUTE_CPP_SCHEDULER */
+ ARM_COMPUTE_ERROR("Recompile with cppthreads=1 to use C++11 scheduler.");
+#endif /* ARM_COMPUTE_CPP_SCHEDULER */
+ }
+ case Type::OMP:
+ {
+#if ARM_COMPUTE_OPENMP_SCHEDULER
+ return support::cpp14::make_unique<OMPScheduler>();
+#else /* ARM_COMPUTE_OPENMP_SCHEDULER */
+ ARM_COMPUTE_ERROR("Recompile with openmp=1 to use openmp scheduler.");
+#endif /* ARM_COMPUTE_OPENMP_SCHEDULER */
+ }
+ default:
+ {
+ ARM_COMPUTE_ERROR("Invalid Scheduler type");
+ break;
+ }
+ }
+}
+} // namespace arm_compute
diff --git a/src/runtime/Utils.cpp b/src/runtime/Utils.cpp
index 81de782399..70494be05c 100644
--- a/src/runtime/Utils.cpp
+++ b/src/runtime/Utils.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -23,16 +23,20 @@
*/
#include "arm_compute/runtime/Utils.h"
+#include "arm_compute/runtime/NEON/NEScheduler.h"
+
#include <map>
#include <string>
-using namespace arm_compute;
-
+namespace arm_compute
+{
+#ifndef DOXYGEN_SKIP_THIS
static const std::string information =
#include "arm_compute_version.embed"
;
+#endif /* DOXYGEN_SKIP_THIS */
-const std::string &arm_compute::string_from_scheduler_type(Scheduler::Type t)
+const std::string &string_from_scheduler_type(Scheduler::Type t)
{
static std::map<Scheduler::Type, const std::string> scheduler_type_map =
{
@@ -44,3 +48,17 @@ const std::string &arm_compute::string_from_scheduler_type(Scheduler::Type t)
return scheduler_type_map[t];
}
+
+void schedule_kernel_on_ctx(IRuntimeContext *ctx, ICPPKernel *kernel, const IScheduler::Hints &hints)
+{
+ if(ctx)
+ {
+ ARM_COMPUTE_ERROR_ON(ctx->scheduler() == nullptr);
+ ctx->scheduler()->schedule(kernel, hints);
+ }
+ else
+ {
+ NEScheduler::get().schedule(kernel, hints);
+ }
+}
+} // namespace arm_compute