blob: 4063cc1c0009ed8ec3afc7a56896d594bbe2a130 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2017-2020 Arm Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "arm_compute/runtime/Scheduler.h"
25
26#include "arm_compute/core/Error.h"
Matthew Bentham758b5ba2020-03-05 23:37:48 +000027#include "support/MemorySupport.h"
Georgios Pinitas12833d02019-07-25 13:31:10 +010028
Anthony Barbier6ff3b192017-09-04 18:44:23 +010029#if ARM_COMPUTE_CPP_SCHEDULER
30#include "arm_compute/runtime/CPP/CPPScheduler.h"
Anthony Barbierac69aa12017-07-03 17:39:37 +010031#endif /* ARM_COMPUTE_CPP_SCHEDULER */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010032
33#include "arm_compute/runtime/SingleThreadScheduler.h"
34
35#if ARM_COMPUTE_OPENMP_SCHEDULER
36#include "arm_compute/runtime/OMP/OMPScheduler.h"
Anthony Barbierac69aa12017-07-03 17:39:37 +010037#endif /* ARM_COMPUTE_OPENMP_SCHEDULER */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010038
39using namespace arm_compute;
40
41#if !ARM_COMPUTE_CPP_SCHEDULER && ARM_COMPUTE_OPENMP_SCHEDULER
42Scheduler::Type Scheduler::_scheduler_type = Scheduler::Type::OMP;
43#elif ARM_COMPUTE_CPP_SCHEDULER && !ARM_COMPUTE_OPENMP_SCHEDULER
44Scheduler::Type Scheduler::_scheduler_type = Scheduler::Type::CPP;
45#elif ARM_COMPUTE_CPP_SCHEDULER && ARM_COMPUTE_OPENMP_SCHEDULER
46Scheduler::Type Scheduler::_scheduler_type = Scheduler::Type::CPP;
Anthony Barbierac69aa12017-07-03 17:39:37 +010047#else /* ARM_COMPUTE_*_SCHEDULER */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010048Scheduler::Type Scheduler::_scheduler_type = Scheduler::Type::ST;
Anthony Barbierac69aa12017-07-03 17:39:37 +010049#endif /* ARM_COMPUTE_*_SCHEDULER */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010050
Georgios Pinitas12833d02019-07-25 13:31:10 +010051std::shared_ptr<IScheduler> Scheduler::_custom_scheduler = nullptr;
52
53namespace
54{
55std::map<Scheduler::Type, std::unique_ptr<IScheduler>> init()
56{
57 std::map<Scheduler::Type, std::unique_ptr<IScheduler>> m;
58 m[Scheduler::Type::ST] = support::cpp14::make_unique<SingleThreadScheduler>();
59#if defined(ARM_COMPUTE_CPP_SCHEDULER)
60 m[Scheduler::Type::CPP] = support::cpp14::make_unique<CPPScheduler>();
61#endif // defined(ARM_COMPUTE_CPP_SCHEDULER)
62#if defined(ARM_COMPUTE_OPENMP_SCHEDULER)
63 m[Scheduler::Type::OMP] = support::cpp14::make_unique<OMPScheduler>();
64#endif // defined(ARM_COMPUTE_OPENMP_SCHEDULER)
65
66 return m;
67}
68} // namespace
69
70std::map<Scheduler::Type, std::unique_ptr<IScheduler>> Scheduler::_schedulers = init();
71
Anthony Barbier6ff3b192017-09-04 18:44:23 +010072void Scheduler::set(Type t)
73{
74 ARM_COMPUTE_ERROR_ON(!Scheduler::is_available(t));
75 _scheduler_type = t;
76}
77
78bool Scheduler::is_available(Type t)
79{
Georgios Pinitas12833d02019-07-25 13:31:10 +010080 if(t == Type::CUSTOM)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010081 {
Georgios Pinitas12833d02019-07-25 13:31:10 +010082 return _custom_scheduler != nullptr;
83 }
84 else
85 {
86 return _schedulers.find(t) != _schedulers.end();
Anthony Barbier6ff3b192017-09-04 18:44:23 +010087 }
88}
89
90Scheduler::Type Scheduler::get_type()
91{
92 return _scheduler_type;
93}
94
95IScheduler &Scheduler::get()
96{
Georgios Pinitas12833d02019-07-25 13:31:10 +010097 if(_scheduler_type == Type::CUSTOM)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010098 {
Georgios Pinitas12833d02019-07-25 13:31:10 +010099 if(_custom_scheduler == nullptr)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100100 {
Georgios Pinitas12833d02019-07-25 13:31:10 +0100101 ARM_COMPUTE_ERROR("No custom scheduler has been setup. Call set(std::shared_ptr<IScheduler> &scheduler) before Scheduler::get()");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100102 }
Georgios Pinitas12833d02019-07-25 13:31:10 +0100103 else
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100104 {
Georgios Pinitas12833d02019-07-25 13:31:10 +0100105 return *_custom_scheduler;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100106 }
107 }
Georgios Pinitas12833d02019-07-25 13:31:10 +0100108 else
109 {
110 auto it = _schedulers.find(_scheduler_type);
111 if(it != _schedulers.end())
112 {
113 return *it->second;
114 }
115 else
116 {
117 ARM_COMPUTE_ERROR("Invalid Scheduler type");
118 }
119 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100120}
121
Anthony Barbiere8a49832018-01-18 10:04:05 +0000122void Scheduler::set(std::shared_ptr<IScheduler> scheduler)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100123{
Anthony Barbiere8a49832018-01-18 10:04:05 +0000124 _custom_scheduler = std::move(scheduler);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100125 set(Type::CUSTOM);
126}