Skip to content

Commit 60e255e

Browse files
committed
Fixing loop-end condition
1 parent 802eb72 commit 60e255e

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

libs/core/coroutines/include/hpx/coroutines/thread_enums.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,15 @@ namespace hpx::threads {
206206
/// local thread number associated with this hint. Local thread numbers
207207
/// are indexed from zero. It is up to the scheduler to decide how to
208208
/// interpret thread numbers that are larger than the number of threads
209-
/// available to the scheduler. Typically thread numbers will wrap
209+
/// available to the scheduler. Typically, thread numbers will wrap
210210
/// around when too large.
211211
thread = 1,
212212

213213
/// A hint that tells the scheduler to prefer scheduling a task on the
214214
/// NUMA domain associated with this hint. NUMA domains are indexed from
215215
/// zero. It is up to the scheduler to decide how to interpret NUMA
216216
/// domain indices that are larger than the number of available NUMA
217-
/// domains to the scheduler. Typically indices will wrap around when
217+
/// domains to the scheduler. Typically, indices will wrap around when
218218
/// too large.
219219
numa = 2,
220220
};
@@ -295,7 +295,7 @@ namespace hpx::threads {
295295
}
296296

297297
///////////////////////////////////////////////////////////////////////////
298-
/// \enum thread_placement_hint
298+
/// \enum thread_execution_hint
299299
///
300300
/// The type of hint given to the scheduler related running a thread as a
301301
/// child directly in the context of the parent thread

libs/core/executors/include/hpx/executors/detail/index_queue_spawning.hpp

+38-19
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ namespace hpx::parallel::execution::detail {
6565
template <typename F, typename Ts>
6666
void do_work_chunk(F&& f, Ts&& ts, std::uint32_t const index) const
6767
{
68-
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
68+
#if defined(HPX_HAVE_ITTNOTIFY) && HPX_HAVE_ITTNOTIFY != 0 && \
69+
!defined(HPX_HAVE_APEX)
6970
static hpx::util::itt::event notify_event(
7071
"set_value_loop_visitor_static::do_work_chunk(chunking)");
7172

@@ -150,7 +151,7 @@ namespace hpx::parallel::execution::detail {
150151
// Finish the work for one worker thread. If this is not the last worker
151152
// thread to finish, it will only decrement the counter. If it is the
152153
// last thread it will call set_exception if there is an exception.
153-
// Otherwise it will call set_value on the shared state.
154+
// Otherwise, it will call set_value on the shared state.
154155
void finish() const
155156
{
156157
if (--(state->tasks_remaining.data_) == 0)
@@ -438,17 +439,21 @@ namespace hpx::parallel::execution::detail {
438439

439440
// Initialize the queues for all worker threads so that worker
440441
// threads can start stealing immediately when they start.
441-
for (std::uint32_t worker_thread = 0; worker_thread != num_threads;
442-
++worker_thread)
442+
if (hint.placement_mode() == placement::breadth_first ||
443+
hint.placement_mode() == placement::breadth_first_reverse)
443444
{
444-
if (hint.placement_mode() == placement::breadth_first ||
445-
hint.placement_mode() == placement::breadth_first_reverse)
445+
for (std::uint32_t worker_thread = 0;
446+
worker_thread != num_threads; ++worker_thread)
446447
{
447448
init_queue_breadth_first(worker_thread, num_chunks);
448449
}
449-
else
450+
}
451+
else
452+
{
453+
// the default for this executor is depth-first placement
454+
for (std::uint32_t worker_thread = 0;
455+
worker_thread != num_threads; ++worker_thread)
450456
{
451-
// the default for this executor is depth-first placement
452457
init_queue_depth_first(worker_thread, num_chunks);
453458
}
454459
}
@@ -546,8 +551,8 @@ namespace hpx::parallel::execution::detail {
546551
auto launch_data = generate_launch_data();
547552
std::size_t const size = launch_data.size();
548553

549-
// Do straight spawning if hierarchical spawning was disabled or we
550-
// have less chunks than our threshold.
554+
// Do straight spawning if hierarchical spawning was disabled or if
555+
// we have less chunks than our threshold.
551556
if (hierarchical_threshold == 0 || hierarchical_threshold >= size)
552557
{
553558
for (std::size_t i = 0; i != size; ++i)
@@ -558,36 +563,50 @@ namespace hpx::parallel::execution::detail {
558563
return;
559564
}
560565

561-
auto task = [desc, pool, launch_data](auto b, auto e) {
562-
for (std::size_t i = b; i != e - 1; ++i)
566+
auto task = [desc, pool, launch_data = HPX_MOVE(launch_data)](
567+
auto b, auto e) mutable {
568+
HPX_ASSERT(b != e);
569+
for (std::size_t i = b + 1; i != e; ++i)
563570
{
564571
auto state = launch_data[i].func.state;
565572
state->template do_work_task<false>(desc, pool,
566-
launch_data[i].bind_to_core, launch_data[i].func);
573+
launch_data[i].bind_to_core,
574+
HPX_MOVE(launch_data[i].func));
567575
}
568576

569-
// directly execute last task
570-
auto state = launch_data[e - 1].func.state;
577+
// directly execute first task
578+
auto state = launch_data[b].func.state;
571579
state->template do_work_task<true>(
572-
desc, pool, false, launch_data[e - 1].func);
580+
desc, pool, false, HPX_MOVE(launch_data[b].func));
573581
};
574582

575583
// run task on small stack
576584
auto post_policy = hpx::execution::experimental::with_stacksize(
577585
policy, threads::thread_stacksize::small_);
586+
auto post_policy_hint =
587+
hpx::execution::experimental::get_hint(post_policy);
588+
post_policy_hint.mode =
589+
hpx::threads::thread_schedule_hint_mode::thread;
590+
578591
std::size_t start = 0;
579-
while (true)
592+
while (start < size)
580593
{
594+
// place the helper thread on the first core of the thread block
595+
post_policy_hint.hint =
596+
first_thread + static_cast<std::uint16_t>(start);
597+
auto core_policy = hpx::execution::experimental::with_hint(
598+
post_policy, post_policy_hint);
599+
581600
auto const stop = start + hierarchical_threshold;
582601
if (stop > size)
583602
{
584603
hpx::detail::post_policy_dispatch<Launch>::call(
585-
post_policy, desc, pool, HPX_MOVE(task), start, size);
604+
core_policy, desc, pool, HPX_MOVE(task), start, size);
586605
break;
587606
}
588607

589608
hpx::detail::post_policy_dispatch<Launch>::call(
590-
post_policy, desc, pool, task, start, stop);
609+
core_policy, desc, pool, task, start, stop);
591610
start = stop;
592611
}
593612
}

libs/core/executors/include/hpx/executors/thread_pool_scheduler_bulk.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ namespace hpx::execution::experimental::detail {
131131
template <typename Ts>
132132
void do_work_chunk(Ts& ts, std::uint32_t const index) const
133133
{
134-
#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
134+
#if defined(HPX_HAVE_ITTNOTIFY) && HPX_HAVE_ITTNOTIFY != 0 && \
135+
!defined(HPX_HAVE_APEX)
135136
static hpx::util::itt::event notify_event(
136137
"set_value_loop_visitor_static::do_work_chunk(chunking)");
137138

@@ -145,7 +146,7 @@ namespace hpx::execution::experimental::detail {
145146
(std::min)(i_begin + task_f->chunk_size, task_f->size);
146147

147148
auto it = std::next(hpx::util::begin(op_state->shape), i_begin);
148-
for (std::uint32_t i = i_begin; i != i_end; (void) ++it, ++i)
149+
for (std::size_t i = i_begin; i != i_end; (void) ++it, ++i)
149150
{
150151
bulk_scheduler_invoke_helper(
151152
index_pack_type{}, op_state->f, *it, ts);
@@ -274,7 +275,7 @@ namespace hpx::execution::experimental::detail {
274275
// Finish the work for one worker thread. If this is not the last worker
275276
// thread to finish, it will only decrement the counter. If it is the
276277
// last thread it will call set_error if there is an exception.
277-
// Otherwise it will call set_value on the connected receiver.
278+
// Otherwise, it will call set_value on the connected receiver.
278279
void finish() const
279280
{
280281
if (--(op_state->tasks_remaining.data_) == 0)

0 commit comments

Comments
 (0)