| 75 | } |
| 76 | |
| 77 | void OMPScheduler::schedule_op(ICPPKernel *kernel, const Hints &hints, const Window &window, ITensorPack &tensors) |
| 78 | { |
| 79 | // The rest of the logic in this function does not handle the |
| 80 | // split_dimensions_all case so we defer to IScheduler::schedule_common() |
| 81 | if (hints.split_dimension() == IScheduler::split_dimensions_all) |
| 82 | { |
| 83 | return schedule_common(kernel, hints, window, tensors); |
| 84 | } |
| 85 | |
| 86 | ARM_COMPUTE_ERROR_ON_MSG(!kernel, "The child class didn't set the kernel"); |
| 87 | ARM_COMPUTE_ERROR_ON_MSG(hints.strategy() == StrategyHint::DYNAMIC, |
| 88 | "Dynamic scheduling is not supported in OMPScheduler"); |
| 89 | |
| 90 | const Window &max_window = window; |
| 91 | const unsigned int num_iterations = max_window.num_iterations(hints.split_dimension()); |
| 92 | const unsigned int mws = kernel->get_mws(CPUInfo::get(), _num_threads); |
| 93 | |
| 94 | // Ensure each thread has mws amount of work to do (i.e. ceil(num_iterations / mws) threads) |
| 95 | const unsigned int candidate_num_threads = (num_iterations + mws - 1) / mws; |
| 96 | |
| 97 | // Cap the number of threads to be spawn with the size of the thread pool |
| 98 | const unsigned int num_threads = std::min(candidate_num_threads, _num_threads); |
| 99 | |
| 100 | if (!kernel->is_parallelisable() || num_threads == 1) |
| 101 | { |
| 102 | ThreadInfo info; |
| 103 | info.cpu_info = &cpu_info(); |
| 104 | kernel->run_op(tensors, max_window, info); |
| 105 | } |
| 106 | else |
| 107 | { |
| 108 | const unsigned int num_windows = num_threads; |
| 109 | std::vector<IScheduler::Workload> workloads(num_windows); |
| 110 | for (unsigned int t = 0; t < num_windows; t++) |
| 111 | { |
| 112 | //Capture 't' by copy, all the other variables by reference: |
| 113 | workloads[t] = [t, &hints, &max_window, &num_windows, &kernel, &tensors](const ThreadInfo &info) |
| 114 | { |
| 115 | Window win = max_window.split_window(hints.split_dimension(), t, num_windows); |
| 116 | win.validate(); |
| 117 | kernel->run_op(tensors, win, info); |
| 118 | }; |
| 119 | } |
| 120 | run_workloads(workloads); |
| 121 | } |
| 122 | } |
| 123 | #ifndef DOXYGEN_SKIP_THIS |
| 124 | void OMPScheduler::run_workloads(std::vector<arm_compute::IScheduler::Workload> &workloads) |
| 125 | { |
no test coverage detected