#include "cpu/aarch64/acl_thread.hpp"
#if DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_THREADPOOL
#include "cpu/aarch64/acl_threadpool_scheduler.hpp"
#endif
#include "cpu/aarch64/acl_benchmark_scheduler.hpp"
namespace dnnl {
namespace impl {
namespace cpu {
namespace aarch64 {
namespace acl_thread_utils {
#if DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_OMP
void acl_thread_bind() {
static std::once_flag flag_once;
const int max_threads = dnnl_get_max_threads();
std::call_once(flag_once, [&]() {
arm_compute::Scheduler::get().set_num_threads(max_threads);
});
}
void acl_set_benchmark_scheduler_default() {
static std::once_flag flag_once;
arm_compute::IScheduler *_real_scheduler = &arm_compute::Scheduler::get();
std::shared_ptr<arm_compute::IScheduler> benchmark_scheduler
= std::make_unique<benchmark_scheduler_t>(*_real_scheduler);
std::call_once(flag_once, [&]() {
arm_compute::Scheduler::set(
std::static_pointer_cast<arm_compute::IScheduler>(
benchmark_scheduler));
});
}
#endif
#if DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_THREADPOOL
void acl_set_tp_scheduler() {
static thread_local std::once_flag flag_once;
std::call_once(flag_once, [&]() {
std::shared_ptr<arm_compute::IScheduler> threadpool_scheduler
= std::make_unique<ThreadpoolScheduler>();
arm_compute::Scheduler::set(threadpool_scheduler);
});
}
void acl_set_threadpool_num_threads() {
using namespace dnnl::impl::threadpool_utils;
static thread_local std::once_flag flag_once;
threadpool_interop::threadpool_iface *tp = get_active_threadpool();
bool is_main = get_active_threadpool() == tp;
if (is_main) {
const int num_threads = (tp) ? dnnl_get_max_threads() : 1;
std::call_once(flag_once, [&]() {
arm_compute::Scheduler::get().set_num_threads(num_threads);
});
}
}
void acl_set_tp_benchmark_scheduler() {
static thread_local std::once_flag flag_once;
std::call_once(flag_once, [&]() {
std::unique_ptr<arm_compute::IScheduler> threadpool_scheduler
= std::make_unique<ThreadpoolScheduler>();
arm_compute::IScheduler *_real_scheduler = nullptr;
_real_scheduler = threadpool_scheduler.release();
std::shared_ptr<arm_compute::IScheduler> benchmark_scheduler
= std::make_unique<BenchmarkScheduler>(*_real_scheduler);
arm_compute::Scheduler::set(benchmark_scheduler);
});
}
#endif
void set_acl_threading() {
#if DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_OMP
acl_thread_bind();
if (get_verbose(verbose_t::profile_externals)) {
acl_set_benchmark_scheduler_default();
}
#endif
#if DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_THREADPOOL
if (get_verbose(verbose_t::profile_externals)) {
acl_set_tp_benchmark_scheduler();
} else {
acl_set_tp_scheduler();
}
#endif
}
}
} } } }